YJango:TensorFlow高层API Custom Estimator建立CNN+RNN的演示

简介: TensorFlow 目前是最为常用的深度学习框架。然而从头编写整个机器学习流程却是一件繁琐的工作。虽然上有 Keras 帮助减轻代码量,但这次 TensorFlow 自己提供了高阶 API estimators。

目录

前言

机器学习

  • 两大模块:数据、模型
  • 三个阶段:训练、评估、预测

优势

实现

  • 数据集:TFRecord+Dataset
  • 定义input_fn
  • 定义model_fn

    • 正向传播

      • CNN:二维卷积层
      • RNN:循环层(双向循环层)
      • CNN+RNN:一维卷积层+循环层
    • 预测分支
    • 训练分支
    • 评估分支
  • 创建estimator
  • 训练
  • 评估
  • 预测
  • 可视化

前言

该文是YJango:TensorFlow中层API Datasets+TFRecord的数据导入的后续。

知道了如何用中层API:Dataset来导入数据后,下面介绍如何接着用高层API:Estimator来用下面四个网络结构来完成mnist手写数字识别。

  • 二维卷积神经网络
  • 循环神经网络
  • 双向循环神经网络
  • 一维卷积+循环网络

机器学习

人们常说深度学习是黑箱,我们同样也希望使用深度学习可以像使用黑箱工具那样简单。可事实却并非如此。以监督学习为例:

我们的最终目标是:希望获得一个可以输入问题就能获得答案的算法。

可为了获得该算法,要先搜集数据,然后将数据处理成适应计算机或模型的形式。根据目的分成训练集、验证集、测试集。经过反复的选择、训练、调参、评估后确定最终投入应用的模型。

上述流程可分为训练评估预测三个阶段。不同阶段:

  • 使用的模型数据处理记录操作是相同的。
  • 使用的数据集模型操作不同。

一、训练:

  • 模型操作:正向传播+反向传播。遍历整个训练集若干次,用于更新模型权重。
  • 数据集:训练集。

二、评估:

  • 模型操作:正向传播。遍历每个数据集一次,算出评估指标来衡量模型表现。
  • 数据集:会使用多个数据集进行评估,但意义不同。
  • 训练集:评估模型能力是否足够,判断是否欠拟合。
  • 验证集:其本质也属于训练集的一部分。评估模型的普遍性,和训练集的评估结果一起来判断是否过拟合。因为会根据验证集的结果来调整模型参数,所以模型间接的“见过”验证集的数据。
  • 测试集:模型从未见过的数据,用于评估模型的最终表现,决定是否选择新模型。

注:训练集和验证集都无法作为最终表现的考核标准。评估模型的最终表现一定要用模型从未见过的数据。就如同考核高考解题能力的方法是考核我们从没做过的题目一样,因为我们可以记住做过题目的答案。

三、预测:

  • 模型操作:正向传播。用训练好的模型算出所有预测值即可。
  • 数据集:只有输入的实际应用数据。

优势

一、为什么用Estimator API?

正如先前所说机器学习可分为训练、评估、预测三个阶段,每个阶段又都会用到相同的模型和数据处理方法。

而Tensorflow的高层API:Estimator正是对共用部分使用通用方法,而在不同的阶段实现具体的控制。

共用部分:

  • model_fn:构建模型
  • input_fn:导入数据 + 数据集的处理(结合中层API:Dataset)
  • 其他:帮助控制sessions、graphs、loops、logging

三个阶段:通过调用对应的train(), evaluate(), predict()方法来执行不同的阶段。


实现

一、数据集

这里直接使用上篇文章中所描述的方法(没看过的先看上一篇),将MNIST数据集先写成tfrecord文件,再用dataset API导入,进行batch,shuffle,padding等操作。需要文件:tfrecorder.py

1. 制作TFrecord文件

# 所需库包
import pandas as pd
import numpy as np
import tensorflow as tf
# 需要从我给的github上获得tfrecorder
from tfrecorder import TFrecorder
from matplotlib import pyplot as plt
import matplotlib.image as mpimg
%pylab inline

# mnist数据
mnist = tf.contrib.learn.datasets.load_dataset("mnist")

# 指定如何写成tfrecord文件的信息
# 每一个row是一个feature
df = pd.DataFrame({'name':['image','label'],
                  'type':['float32','int64'],
                  'shape':[(784,),()],
                  'isbyte':[False,False],
                  "length_type":['fixed','fixed'],
                  "default":[np.NaN,np.NaN]})
# 实例化该类
tfr = TFrecorder()

# 写训练集和测试集的位置
mkdir mnist_tfrecord mnist_tfrecord/train mnist_tfrecord/test

使用tfr.feature_writer方法创建样本写入字典,一个样本一个样本的写入TFRecord file中。

由于使用tfrecord时往往是拥有大量数据的情况,需要一点点写入。

1.1. 训练集

# 用该方法写训练集的tfrecord文件
dataset = mnist.train
path = 'mnist_tfrecord/train/train'
# 每个tfrecord文件写多少个样本
num_examples_per_file = 1000
# 当前写的样本数
num_so_far = 0
# 要写入的文件
writer = tf.python_io.TFRecordWriter('%s%s_%s.tfrecord' %(path, num_so_far, num_examples_per_file))
# 写多个样本
for i in np.arange(dataset.num_examples):
    # 要写到tfrecord文件中的字典
    features = {}
    # 写一个样本的图片信息存到字典features中
    tfr.feature_writer(df.iloc[0], dataset.images[i], features)
    # 写一个样本的标签信息存到字典features中
    tfr.feature_writer(df.iloc[1], dataset.labels[i], features)
    
    tf_features = tf.train.Features(feature= features)
    tf_example = tf.train.Example(features = tf_features)
    tf_serialized = tf_example.SerializeToString()
    writer.write(tf_serialized)
    # 每写了num_examples_per_file个样本就令生成一个tfrecord文件
    if i%num_examples_per_file ==0 and i!=0:
        writer.close()
        num_so_far = i
        writer = tf.python_io.TFRecordWriter('%s%s_%s.tfrecord' %(path, num_so_far, i+num_examples_per_file))
        print('saved %s%s_%s.tfrecord' %(path, num_so_far, i+num_examples_per_file))
writer.close()
# 把指定如何写成tfrecord文件的信息保存起来
data_info_path = 'mnist_tfrecord/data_info.csv'
df.to_csv(data_info_path,index=False)

1.2. 测试集

# 用该方法写测试集的tfrecord文件
dataset = mnist.test
path = 'mnist_tfrecord/test/test'
# 每个tfrecord文件写多少个样本
num_examples_per_file = 1000
# 当前写的样本数
num_so_far = 0
# 要写入的文件
writer = tf.python_io.TFRecordWriter('%s%s_%s.tfrecord' %(path, num_so_far, num_examples_per_file))
# 写多个样本
for i in np.arange(dataset.num_examples):
    # 要写到tfrecord文件中的字典
    features = {}
    # 写一个样本的图片信息存到字典features中
    tfr.feature_writer(df.iloc[0], dataset.images[i], features)
    # 写一个样本的标签信息存到字典features中
    tfr.feature_writer(df.iloc[1], dataset.labels[i], features)
    
    tf_features = tf.train.Features(feature= features)
    tf_example = tf.train.Example(features = tf_features)
    tf_serialized = tf_example.SerializeToString()
    writer.write(tf_serialized)
    # 每写了num_examples_per_file个样本就令生成一个tfrecord文件
    if i%num_examples_per_file ==0 and i!=0:
        writer.close()
        num_so_far = i
        writer = tf.python_io.TFRecordWriter('%s%s_%s.tfrecord' %(path, num_so_far, i+num_examples_per_file))
        print('saved %s%s_%s.tfrecord' %(path, num_so_far, i+num_examples_per_file))
writer.close()
# 把指定如何写成tfrecord文件的信息保存起来
data_info_path = 'mnist_tfrecord/data_info.csv'
df.to_csv(data_info_path,index=False)

二、生成input_fn

送入到Estimator中的input_fn需要是一个函数,而不是具体的数据。

所以这里用input_fn_maker来控制如何生成不同的input_fn函数。

tfr = TFrecorder()
def input_fn_maker(path, data_info_path, shuffle=False, batch_size = 1, epoch = 1, padding = None):
    def input_fn():
        # tfr.get_filenames会返回包含path下的所有tfrecord文件的list
        # shuffle会让这些文件的顺序打乱
        filenames = tfr.get_filenames(path=path, shuffle=shuffle)
        dataset=tfr.get_dataset(paths=filenames, data_info=data_info_path, shuffle = shuffle, 
                            batch_size = batch_size, epoch = epoch, padding =padding)
        iterator = dataset.make_one_shot_iterator()
        return iterator.get_next()
    return input_fn
padding_info = ({'image':[784,],'label':[]})
# 生成3个input_fn
test_input_fn = input_fn_maker('mnist_tfrecord/test/',  'mnist_tfrecord/data_info.csv',
                               padding = padding_info)
train_input_fn = input_fn_maker('mnist_tfrecord/train/',  'mnist_tfrecord/data_info.csv', shuffle=True, batch_size = 512,
                               padding = padding_info)
# 用来评估训练集用,不想要shuffle
train_eval_fn = input_fn_maker('mnist_tfrecord/train/',  'mnist_tfrecord/data_info.csv', batch_size = 512,
                               padding = padding_info)
# input_fn在执行时会返回一个字典,里面的key对应着不同的feature(包括label在内)

完整代码可以在MNIST TFrecord.ipynb找到。

三、model_fn

模型函数必须要有features, mode两个参数,可自己选择加入labels(YJango习惯把label也放进features中)。最后要返回特定的tf.estimator.EstimatorSpec()

模型有三个阶段都共用的正向传播部分,和由mode值来控制返回不同tf.estimator.EstimatorSpec的三个分支。

def model_fn(features, mode):
    # reshape 784维的图片到28x28的平面表达,1为channel数
    features['image'] = tf.reshape(features['image'],[-1,28,28,1])

1. 正向传播

这里使用tf.layers来搭建模型,

要点:

  • 记住tensor在每层前后的shape
  • 记住shape上每个dimension上的意义
  • 给每一层都赋予name,用于debug和方便后续操作。

注:虽然我循序罗列了不同结构,但请一次只拿一个使用

注:关于下面网络的搭建,不明白的细节可以问我。

1.1. 二维卷积层

定义LeNet模型。

# shape: [None,28,28,1]
    conv1 = tf.layers.conv2d(
        inputs=features['image'],
        filters=32,
        kernel_size=[5, 5],
        padding="same",
        activation=tf.nn.relu,
        name = 'conv1')
    # shape: [None,28,28,32]
    pool1 = tf.layers.max_pooling2d(inputs=conv1, pool_size=[2, 2], strides=2, name= 'pool1')
    # shape: [None,14,14,32]
    conv2 = tf.layers.conv2d(
        inputs=pool1,
        filters=64,
        kernel_size=[5, 5],
        padding="same",
        activation=tf.nn.relu,
        name = 'conv2')
    # shape: [None,14,14,64]
    pool2 = tf.layers.max_pooling2d(inputs=conv2, pool_size=[2, 2], strides=2, name= 'pool2')
    # shape: [None,7,7,64]
    pool2_flat = tf.reshape(pool2, [-1, 7 * 7 * 64], name= 'pool2_flat')
    # shape: [None,3136]
    dense1 = tf.layers.dense(inputs=pool2_flat, units=1024, activation=tf.nn.relu, name= 'dense1')
    # dropout只在当mode为tf.estimator.ModeKeys.TRAIN时才使用
    dropout = tf.layers.dropout(inputs=dense1, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
    # shape: [None,1024]
    logits = tf.layers.dense(inputs=dropout, units=10, name= 'output')
    # shape: [None,10]

1.2. 循环层

定义两层循环层模型。

# shape: [None,28,28,1]
    # create RNN cells:
    rnn_cells = [tf.nn.rnn_cell.GRUCell(dim,kernel_initializer=tf.orthogonal_initializer) for dim in [128,256]]
    # stack cells for multi-layers RNN
    multi_rnn_cell = tf.nn.rnn_cell.MultiRNNCell(rnn_cells)
    # create RNN layers
    outputs, last_state = tf.nn.dynamic_rnn(cell=multi_rnn_cell,
                                   inputs=tf.reshape(features['image'],[-1,28,28]),
                                   dtype=tf.float32)
    # shape: outputs: [None,28,256]
    # shape: last_state: [None,256]
    dense1 = tf.layers.dense(inputs=last_state[1], units=1024, activation=tf.nn.relu, name= 'dense1')
    # shape: [None,1024]
    dropout = tf.layers.dropout(inputs=dense1, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
    logits = tf.layers.dense(inputs=dense1, units=10, name= 'output')
    # shape: [None,10]

1.3. 双向循环层

定义两个双向循环层模型。

# shape: [None,28,28,1]
    # create RNN cells:
    rnn_fcells = [tf.nn.rnn_cell.GRUCell(dim,kernel_initializer=tf.orthogonal_initializer) for dim in [128,256]]
    rnn_bcells = [tf.nn.rnn_cell.GRUCell(dim,kernel_initializer=tf.orthogonal_initializer) for dim in [128,256]]
    # stack cells for multi-layers RNN
    multi_rnn_fcell = tf.nn.rnn_cell.MultiRNNCell(rnn_fcells)
    multi_rnn_bcell = tf.nn.rnn_cell.MultiRNNCell(rnn_bcells)
    # create RNN layers
    ((outputs_fw, outputs_bw),(last_state_fw, last_state_bw)) = tf.nn.bidirectional_dynamic_rnn(
                                   cell_fw=multi_rnn_fcell,
                                   cell_bw=multi_rnn_bcell,
                                   inputs=tf.reshape(features['image'],[-1,28,28]),
                                   dtype=tf.float32)
    # shape: outputs: [None,28,256]
    # shape: last_state: [None,256]
    dense1 = tf.layers.dense(inputs=last_state_fw[1]+last_state_bw[1], units=1024, activation=tf.nn.relu, name= 'dense1')
    # shape: [None,1024]
    dropout = tf.layers.dropout(inputs=dense1, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
    logits = tf.layers.dense(inputs=dense1, units=10, name= 'output')
    # shape: [None,10]

1.4. 一维卷积层+循环层模型

定义一维卷基层+一维maxpool+循环层模型。

# shape: [None,28,28,1]
    conv1 = tf.layers.conv1d(
            inputs = tf.reshape(features['image'],[-1,28,28]), 
            filters = 32, 
            kernel_size = 5,
            padding="same",
            activation=tf.nn.relu,
            name = 'conv1')
    # shape: [None,28,32]
    pool1 = tf.layers.max_pooling1d(inputs = conv1, 
                          pool_size=2,
                          strides=2,
                          name = 'pool1')
    # shape: [None,14,32]
    # create RNN cells:
    rnn_cells = [tf.nn.rnn_cell.GRUCell(dim,kernel_initializer=tf.orthogonal_initializer) for dim in [128,256]]
    # stack cells for multi-layers RNN
    multi_rnn_cell = tf.nn.rnn_cell.MultiRNNCell(rnn_cells)
    # create RNN layers
    outputs, last_state = tf.nn.dynamic_rnn(cell=multi_rnn_cell,
                                   inputs=pool1,
                                   dtype=tf.float32)
    # shape: outputs: [None,14,256]
    # shape: last_state: [None,256]
    dense1 = tf.layers.dense(inputs=last_state[1], units=1024, activation=tf.nn.relu, name= 'dense1')
    # shape: [None,1024]
    dropout = tf.layers.dropout(inputs=dense1, rate=0.4, training=mode == tf.estimator.ModeKeys.TRAIN)
    logits = tf.layers.dense(inputs=dense1, units=10, name= 'output')
    # shape: [None,10]

想要换成不同的模型,只需改变正向传播部分的代码即可。

注:不同网络结构训练1epoch+评估的结构可以在CNN.ipynbRNN.ipynbbiRNN.ipynbCNN_RNN.ipynb中找到。

注:CNN之后的模型并不意味着更好,这里只是为了展示你可以使用任何模型结构来进行学习。还有残差网络的跳层链接,batchnorm层,注意力机制等,至于如何选择,主要是在于你的任务是否具有符合这些特殊层的结构特点。详细的请参考:

YJango:深层神经网络设计理念(在线+视频+幻灯片)

2. 预测分支

# 创建predictions字典,里面写进所有你想要在预测值输出的数值
    # 隐藏层的数值也可以,这里演示了输出所有隐藏层层结果。
    # 字典的key是模型,value给的是对应的tensor
    predictions = {
        "image":features['image'],
        "conv1_out":conv1,
        "pool1_out":pool1,
        "conv2_out":conv2,
        "pool2_out":pool2,
        "pool2_flat_out":pool2_flat,
        "dense1_out":dense1,
        "logits":logits,
        "classes": tf.argmax(input=logits, axis=1),
        "labels": features['label'],
        "probabilities": tf.nn.softmax(logits, name="softmax_tensor")
        }
    # 当mode为tf.estimator.ModeKeys.PREDICT时,我们就让模型返回预测的操作
    if mode == tf.estimator.ModeKeys.PREDICT:
        return tf.estimator.EstimatorSpec(mode=mode, predictions=predictions)

3. 训练分支

# 训练和评估时都会用到loss
    loss = tf.losses.sparse_softmax_cross_entropy(labels=features['label'], logits=logits)
    # 训练分支
    if mode == tf.estimator.ModeKeys.TRAIN:
        optimizer = tf.train.AdamOptimizer(learning_rate=1e-3)
        train_op = optimizer.minimize(
        loss=loss,
        # global_step用于记录训练了多少步
        global_step=tf.train.get_global_step())
        # 返回的tf.estimator.EstimatorSpec根据
        return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op)

4. 评估分支

# 注意评估的时候,模型和训练时一样,是一个循环的loop,不断累积计算评估指标。
    # 其中有两个局部变量total和count来控制
    # 把网络中的某个tensor结果直接作为字典的value是不好用的
    # loss的值是始终做记录的,eval_metric_ops中是额外想要知道的评估指标
    eval_metric_ops = {"accuracy": tf.metrics.accuracy(labels=features['label'], predictions=predictions["classes"])}
    # 不好用:eval_metric_ops = {"probabilities": predictions["probabilities"]}
    return tf.estimator.EstimatorSpec(mode=mode, loss=loss, eval_metric_ops=eval_metric_ops)

四、创建estimator

注意:送入的model_fninput_fn一样是一个函数,不可以是model_fn()返回结果

# model_dir 表示模型要存到哪里
mnist_classifier = tf.estimator.Estimator(
    model_fn=model_fn, model_dir="mnist_model_cnn")

训练后的模型参数会保存在model_dir中,随着训练在目录下生成拥有类似下面内容的checkpoint文件。

model_checkpoint_path: "model.ckpt-860"
all_model_checkpoint_paths: "model.ckpt-1"
all_model_checkpoint_paths: "model.ckpt-430"
all_model_checkpoint_paths: "model.ckpt-431"
all_model_checkpoint_paths: "model.ckpt-860"

当你再次运行相同model_dir的Estimator时,它默认会读取model_checkpoint_path: "model.ckpt-860"的模型权重。

如果想要改变读取的检查点到之前的某个时刻,可以改变:

model_checkpoint_path: "model.ckpt-431"
all_model_checkpoint_paths: "model.ckpt-1"
all_model_checkpoint_paths: "model.ckpt-430"
all_model_checkpoint_paths: "model.ckpt-431"
all_model_checkpoint_paths: "model.ckpt-860"

五、训练

1. 日志

# 在训练或评估的循环中,每50次print出一次字典中的数值
tensors_to_log = {"probabilities": "softmax_tensor"}
logging_hook = tf.train.LoggingTensorHook(tensors=tensors_to_log, every_n_iter=50)

2. 训练

  • hooks:如果不送值,则训练过程中不会显示字典中的数值
  • steps:指定了训练多少次,如果不送值,则训练到dataset API遍历完数据集为止
  • max_steps:指定了最大训练次数
mnist_classifier.train(input_fn=train_input_fn, hooks=[logging_hook])

如果再次运行,同时没有限制最大训练次数,那么网络会从最后一个checkpoint读取模型权重接着训练。

六、评估

# 训练集
eval_results = mnist_classifier.evaluate(input_fn=train_eval_fn, checkpoint_path=None)
print('train set')
print(eval_results)
# 测试集
# checkpoint_path是可以指定选择那个时刻保存的权重进行评估
eval_results = mnist_classifier.evaluate(input_fn=test_input_fn, checkpoint_path=None)
print('test set')
print(eval_results)

七、预测

predicts =list(mnist_classifier.predict(input_fn=test_input_fn))

predicts是一个list,list中的元素是dictionary

predicts[0].keys()
# 输出为:
dict_keys(['image', 'conv1_out', 'pool1_out', 'conv2_out', 'pool2_out', 'pool2_flat_out', 'dense1_out', 'logits', 'classes', 'labels', 'probabilities'])

如果想要输出4个第一个卷基层的输出,可以

plt.figure(num=4,figsize=(28,28))
for i in range(4):
    plt.subplot(1,4,i+1)
    plt.imshow(predicts[0]['conv1_out'][:,:,i],cmap = plt.cm.gray)
plt.savefig('conv1_out.png')

八、可视化

tensorboard --logdir=mnist_model_cnn
打开http://localhost:6006 
目录
相关文章
|
9天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
30天前
|
机器学习/深度学习 SQL 数据采集
基于tensorflow、CNN网络识别花卉的种类(图像识别)
基于tensorflow、CNN网络识别花卉的种类(图像识别)
24 1
|
3月前
|
自然语言处理 C# 开发者
Uno Platform多语言开发秘籍大公开:轻松驾驭全球用户,一键切换语言,让你的应用成为跨文化交流的桥梁!
【8月更文挑战第31天】Uno Platform 是一个强大的开源框架,允许使用 C# 和 XAML 构建跨平台的原生移动、Web 和桌面应用程序。本文详细介绍如何通过 Uno Platform 创建多语言应用,包括准备工作、设置多语言资源、XAML 中引用资源、C# 中加载资源以及处理语言更改。通过简单的步骤和示例代码,帮助开发者轻松实现应用的国际化。
41 1
|
3月前
|
机器学习/深度学习 API 算法框架/工具
【Tensorflow+keras】Keras API三种搭建神经网络的方式及以mnist举例实现
使用Keras API构建神经网络的三种方法:使用Sequential模型、使用函数式API以及通过继承Model类来自定义模型,并提供了基于MNIST数据集的示例代码。
54 12
|
3月前
|
机器学习/深度学习 API 算法框架/工具
【Tensorflow+keras】Keras API两种训练GAN网络的方式
使用Keras API以两种不同方式训练条件生成对抗网络(CGAN)的示例代码:一种是使用train_on_batch方法,另一种是使用tf.GradientTape进行自定义训练循环。
40 5
|
3月前
|
UED 开发工具 iOS开发
Uno Platform大揭秘:如何在你的跨平台应用中,巧妙融入第三方库与服务,一键解锁无限可能,让应用功能飙升,用户体验爆棚!
【8月更文挑战第31天】Uno Platform 让开发者能用同一代码库打造 Windows、iOS、Android、macOS 甚至 Web 的多彩应用。本文介绍如何在 Uno Platform 中集成第三方库和服务,如 Mapbox 或 Google Maps 的 .NET SDK,以增强应用功能并提升用户体验。通过 NuGet 安装所需库,并在 XAML 页面中添加相应控件,即可实现地图等功能。尽管 Uno 平台减少了平台差异,但仍需关注版本兼容性和性能问题,确保应用在多平台上表现一致。掌握正确方法,让跨平台应用更出色。
49 0
|
3月前
|
安全 Apache 数据安全/隐私保护
你的Wicket应用安全吗?揭秘在Apache Wicket中实现坚不可摧的安全认证策略
【8月更文挑战第31天】在当前的网络环境中,安全性是任何应用程序的关键考量。Apache Wicket 是一个强大的 Java Web 框架,提供了丰富的工具和组件,帮助开发者构建安全的 Web 应用程序。本文介绍了如何在 Wicket 中实现安全认证,
43 0
|
3月前
|
机器学习/深度学习 数据采集 TensorFlow
从零到精通:TensorFlow与卷积神经网络(CNN)助你成为图像识别高手的终极指南——深入浅出教你搭建首个猫狗分类器,附带实战代码与训练技巧揭秘
【8月更文挑战第31天】本文通过杂文形式介绍了如何利用 TensorFlow 和卷积神经网络(CNN)构建图像识别系统,详细演示了从数据准备、模型构建到训练与评估的全过程。通过具体示例代码,展示了使用 Keras API 训练猫狗分类器的步骤,旨在帮助读者掌握图像识别的核心技术。此外,还探讨了图像识别在物体检测、语义分割等领域的广泛应用前景。
26 0
|
3月前
|
TensorFlow API 算法框架/工具
【Tensorflow 2】Keras API+Estimator的使用
本文介绍了在TensorFlow 2中结合Keras API和Estimator API来构建和训练模型的方法,并提供了一个示例流程,包括构建模型、生成数据集、使用Estimator进行训练以及评估模型性能。
33 3
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
算法金 | 秒懂 AI - 深度学习五大模型:RNN、CNN、Transformer、BERT、GPT 简介
**RNN**,1986年提出,用于序列数据,如语言模型和语音识别,但原始模型有梯度消失问题。**LSTM**和**GRU**通过门控解决了此问题。 **CNN**,1989年引入,擅长图像处理,卷积层和池化层提取特征,经典应用包括图像分类和物体检测,如LeNet-5。 **Transformer**,2017年由Google推出,自注意力机制实现并行计算,优化了NLP效率,如机器翻译。 **BERT**,2018年Google的双向预训练模型,通过掩码语言模型改进上下文理解,适用于问答和文本分类。
154 9

热门文章

最新文章