Tensorflow 2.0 实现神经网络

Tensorflow 2.0 实现神经网络

1.加载fashion_mnist数据集

  • fashion_mnist是一个替代mnist手写数字集的图像数据集,包含60000个示例的训练集和10000个示例的测试集。每个示例都是一个28x28灰度图像,分为10个类别(‘T-shirt’, ‘Trouser’, ‘Pullover’, ‘Dress’, ‘Coat’, ‘Sandal’, ‘Shirt’, ‘Sneaker’, ‘Bag’, ‘Ankle boot’)
  • 下面通过tenssorflow加载该数据集,第一次加载可能稍慢,他要从官网上下载数据集。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt 
import tensorflow as tf

(train_image, train_lable),(test_image, test_label) = tf.keras.datasets.fashion_mnist.load_data() # 加载fashion_mnist数据
# 显示部分数据集
def show_imgs(n_rows, n_cols, x_data, y_data, class_names):
		assert len(x_data) == len(y_data)
		assert n_rows * n_cols < len(y_data)
		plt.figure(figsize = (n_cols * 1.4, n_cols * 1.6))
		for row in range(n_rows):
			for col in range(n_cols):
				index = n_cols * row + col
				plt.subplot(n_rows, n_cols, index+1)
				plt.imshow(x_data[index], cmap='binary', interpolation = 'nearest')
				plt.axis('off')
				plt.title(class_names[y_data[index]])
		plt.show()
class_names = ['T-shirt', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

show_imgs(3, 9, train_image, train_lable, class_names)

运行的结果如下图所示:可以发现他们有10种不同的类别。
在这里插入图片描述

2.搭建三层神经网络

  • 这里搭建神经网络就使用tensorflow中的keras进行搭建,下面详细讲解搭建的过程:

  • 首先在纸上把整个神经网络的框架画出来:

在这里插入图片描述

由于每一张图片维度都是28*28,所以输入层的单元数为28*28;因为是一张图片图像,像素比较多,故需要隐藏层维度大一点在此先设置为128,后面会说明隐藏层的大小对其结果的影响;输出层维度为10,因为有十个类别,最后可以通过softmax将其转化为10个概率,概率最大的那一个就是最佳的类别。

  • 用keras中的顺序模型来搭建神经网络模型,模型是一层一层添加的,按照顺序。

    model = tf.keras.Sequential()
    
  • 添加输入层,使用Flatten(),将输入的二维向量转化为一位向量,即28*28的一维向量,作为输入单元数。

    model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
    
  • 添加隐藏层,使用Dense()层,第一个参数为隐藏层维度,activation参数为激活函数,即通过激活函数传到下一层。

    model.add(tf.keras.layers.Dense(128, activation='relu'))
    

    常用的激活函数有:‘relu’、‘sigmoid’、‘tanh’、‘Leak relu’

    sigmoid函数

    Sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线。在信息科学中,由于其单增以及反函数单增等性质,Sigmoid函数常被用作神经网络的阈值函数,将变量映射到0,1之间。公式如下

    img

    函数图像如下

    img

    tanh函数

    Tanh是双曲函数中的一个,Tanh()为双曲正切。在数学中,双曲正切“Tanh”是由基本双曲函数双曲正弦和双曲余弦推导而来。公式如下

    img

    函数图像如下

    img

    relu函数

    Relu激活函数(The Rectified Linear Unit),用于隐层神经元输出。公式如下

    img

    函数图像如下

    img

  • 添加输出层,使用Dence()层,这里的激活函数就使用softmax函数,将其转化为概率输出。

    model.add(tf.keras.layers.Dense(10, activation='softmax'))
    
  • 至此神经网络模型搭建完毕,我们可以使用model.summary()来查看建立的模型的结构:

    Model: "sequential"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    flatten (Flatten)            (None, 784)               0         
    _________________________________________________________________
    dense (Dense)                (None, 128)               100480    
    _________________________________________________________________
    dense_1 (Dense)              (None, 10)                1290      
    =================================================================
    Total params: 101,770
    Trainable params: 101,770
    Non-trainable params: 0
    _________________________________________________________________
    None
    

    ​ 可以发现每一层的维度大小都有给出,包括每一层的参数个数paramters,这里隐藏层的参数为100480 = (784 + 1)* 128,原因是前面的神经网络的介绍中已经说明,需要多加一个偏置单元,同理后面的1290 = (128 + 1)* 10,也默认添加了一个偏置单元。

  • 对该模型进行编译:

    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc'])
    

    ​ optimizer:是优化方法,常用的优化方法有adam、SGD(随机梯度下降优化器)、RMSprop等;

    ​ loss:是损失函数,常用的有’mes’(均方差),这里由于是分类问题,使用的是前面所讨论的交叉熵损失函数,有两种’sparse_categorical_crossentropy’(适用于最后分类的顺序编码)、‘categorical_crossentropy’(适用于最后分类是独热编码);

    ​ metrics=[‘acc’]可查看每一次的准确率;

  • 用该模型训练数据集:

    history = model.fit(train_image, train_lable, epochs=5,validation_data=(test_image,test_label))
    

    epochs为训练代数,前面是训练集,后面是验证集。每次训练的结果都存在history里面,后面可以根据history将学习曲线以及准确率曲线画出来。

3.模型训练

  • 下面是整个的完整代码,将学习曲线给画出来了。

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt 
    import tensorflow as tf
    (train_image, train_lable),(test_image, test_label) = tf.keras.datasets.fashion_mnist.load_data() # 加载fashion_mnist数据
    def show_imgs(n_rows, n_cols, x_data, y_data, class_names):
    		assert len(x_data) == len(y_data)
    		assert n_rows * n_cols < len(y_data)
    		plt.figure(figsize = (n_cols * 1.4, n_cols * 1.6))
    		for row in range(n_rows):
    			for col in range(n_cols):
    				index = n_cols * row + col
    				plt.subplot(n_rows, n_cols, index+1)
    				plt.imshow(x_data[index], cmap='binary', interpolation = 'nearest')
    				plt.axis('off')
    				plt.title(class_names[y_data[index]])
    		plt.show()
    def plot_learning_curves(history):
    	pd.DataFrame(history.history).plot(figsize=(8,5))
    	plt.grid(True)
    	plt.gca().set_ylim(0, 1)
    	plt.show()
    class_names = ['T-shirt', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
    
    show_imgs(3, 9, train_image, train_lable, class_names)
    # 归一化
    train_image = train_image/255
    test_image = test_image/255
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Flatten(input_shape=(28,28))) # 28*28向量 将矩阵转化为向量
    model.add(tf.keras.layers.Dense(128, activation='relu'))
    model.add(tf.keras.layers.Dense(10, activation='softmax'))
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc'])
    history = model.fit(train_image, train_lable, epochs=5,validation_data=(test_image,test_label))
    plot_learning_curves(history)
    

在这里插入图片描述

通过输出的结果可以发现loss: 0.2982 - acc: 0.8909 - val_loss: 0.3448 - val_acc: 0.8773,准确度为0.89,测试集的准确度为0.87。

4.利用Dropout抑制过拟合

  • 前面我们讨论过,一个神经网络越复杂,神经元越多,隐藏层越多拟合能力越强,但拟合的速度也越慢,更容易产生过拟合现象,那么为了抑制过拟合这里可以使用添加Dropout层抑制过拟合。

     model = tf.keras.Sequential()
    model.add(tf.keras.layers.Flatten(input_shape=(28,28))) # 28*28向量 将矩阵转化为向量
    model.add(tf.keras.layers.Dense(128, activation='relu'))
    model.add(tf.keras.layers.Dropout(0.5)) # 添加Dropout层抑制过拟合
    model.add(tf.keras.layers.Dense(10, activation='softmax'))
    

    就是在之前搭建的神经网络模型的基础上添加一层,参数为0.5代表抑制程度,Dropout的基本原理就是按照一定方法去掉一些神经元,使网络变简单,从而可以抑制过拟合。

5.使用回调函数

  • 前面我们的学习曲线是根据训练完成后的history来画的,但当训练代数比较大时,我们需要时刻监控损失是否下降,以便更好得调整方法,即:在训练数据没有训练完成之前可以返回一些参数做别的操作,这就是回调函数的作用。

  • 首先创建一个存放callbacks的文件夹,具体代码如下:

    logdir = './callbacks' # 如果报错改为绝对路径
    if not os.path.exists(logdir):
    	os.mkdir(logdir)
    output_model_file = os.path.join(logdir,'fashion_mnist_model.h5')
    
  • 这里只设置三种callbacks:TensorBoard、ModelCheckpoint、Earlyshopping;其他的callbacks请参考https://keras-cn.readthedocs.io/en/latest/other/callbacks/官方中文文档

  • TensorBoard:该回调函数是一个可视化的展示器

    TensorBoard是TensorFlow提供的可视化工具,该回调函数将日志信息写入TensorBorad,使得你可以动态的观察训练和测试指标的图像以及不同层的激活值直方图。

    如果已经通过pip安装了TensorFlow,我们可通过下面的命令启动TensorBoard:

    tensorboard --logdir=/full_path_to_your_logs

  • EarlyStoping:当监测值不再改善时,该回调函数将中止训练

  • ModelCheckpoint:该回调函数将在每个epoch后保存模型到filepath

    filepath可以是格式化的字符串,里面的占位符将会被epoch值和传入on_epoch_endlogs关键字所填入

logdir = './callbacks'
if not os.path.exists(logdir):
	os.mkdir(logdir)
output_model_file = os.path.join(logdir,'fashion_mnist_model.h5')
callbacks = [ tf.keras.callbacks.TensorBoard(logdir),
tf.keras.callbacks.ModelCheckpoint(output_model_file,save_best_only=True),]

history = model.fit(train_image, train_lable, epochs=5,validation_data=(test_image,test_label),callbacks = callbacks)
  • 下面是通过tensorboard --logdir=callbacks生成的本地网页数据:http://localhost:6006/(通过端口6006在网页中打开)

在这里插入图片描述

6.(附)上一次用python实现的神经网络改为用Tensorflow2.0实现

# -*- coding:utf-8 -*-
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt 
import tensorflow as tf
from sklearn import datasets
def generate_data(): # 产生数据集
    np.random.seed(0)
    X, y = datasets.make_moons(200, noise=0.20) # 产生月牙形状的数据集
    return X, y

def plot_decision_boundary(model, X, y): # 画决策边界线
    # 设置图像边界最大值与最小值
    x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
    y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
    h = 0.01 #采样间隔
    # 生成网格矩阵
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
    #sample = next(iter(np.c_[xx.ravel(), yy.ravel()]))
    pred = model.predict(np.c_[xx.ravel(), yy.ravel()])
    pred = tf.argmax(pred, axis=1)
    pred_numpy = pred.numpy()
    # 对整个网格矩阵进行预测
    Z = pred_numpy.reshape(xx.shape) # 使预测结果重新变成网格数组大小
    # 画出决策边界
    plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
    # 画出数据点
    plt.scatter(X[:, 0], X[:, 1], s = 20,c=y, cmap=plt.cm.Spectral) 
def main():
    X, y = generate_data()
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.Flatten(input_shape=(2, )))
    model.add(tf.keras.layers.Dense(5, activation='tanh'))
    # model.add(tf.keras.layers.Dropout(0.5)) # 添加Dropout层抑制过拟合
    model.add(tf.keras.layers.Dense(2, activation='softmax'))
    print(model.summary())
    model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['acc'])
    history = model.fit(X, y, epochs=2000)
    model.evaluate(X,y)
    plt.plot(history.epoch,history.history.get('loss'))
    plt.figure(2)
    plot_decision_boundary(model, X, y)
    plt.show()


if __name__ == '__main__':
    main()

在这里插入图片描述
可以发现代码量大大减少,并且得到了和之前相同的效果,并且在这里可以很方便的修改参数(隐藏层维度,隐藏层数量,激活函数等等)

Keras是一个基于Python深度学习库,提供了许多便捷的API用于神经网络的搭建。Keras框架的特点是高度模块化、易于扩展、支持GPU和CPU的混合计算、用户友好,可以方便的构建各种神经网络模型并进行训练和预测。 在Keras中搭建神经网络,首先需要确定神经网络的模型。Keras支持多种模型构建方法,包括序列模型、函数式模型和子类化API等。 序列模型是最简单的一种,它是一个线性的神经网络模型,是多个网络层的线性堆叠,其中的每一层都是前一层的输出作为下一层的输入。可以用以下方式构建一个序列模型: ``` from keras.models import Sequential from keras.layers import Dense model = Sequential() model.add(Dense(units=32, activation='relu', input_dim=100)) model.add(Dense(units=10, activation='softmax')) ``` 函数式模型可以用于构建更复杂的模型,如多输入和多输出的神经网络。可以用以下方式构建一个函数式模型: ``` from keras.layers import Input, Dense from keras.models import Model # This returns a tensor inputs = Input(shape=(784,)) # a layer instance is callable on a tensor, and returns a tensor x = Dense(64, activation='relu')(inputs) x = Dense(64, activation='relu')(x) predictions = Dense(10, activation='softmax')(x) # This creates a model that includes # the Input layer and three Dense layers model = Model(inputs=inputs, outputs=predictions) model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) ``` 子类化API提供了更加灵活的构建方式,可以通过自定义网络层和模型的方式实现复杂的神经网络。可以用以下方式构建一个子类化API模型: ``` import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers class MyModel(keras.Model): def __init__(self): super(MyModel, self).__init__() self.dense1 = layers.Dense(64, activation='relu') self.dense2 = layers.Dense(64, activation='relu') self.dense3 = layers.Dense(10, activation='softmax') def call(self, inputs): x = self.dense1(inputs) x = self.dense2(x) x = self.dense3(x) return x model = MyModel() model.compile(optimizer=keras.optimizers.Adam(learning_rate=1e-3), loss=keras.losses.SparseCategoricalCrossentropy(), metrics=[keras.metrics.SparseCategoricalAccuracy()]) ``` 无论采用何种方式搭建神经网络,都需要进行模型的编译和训练。模型的编译需要指定优化器、损失函数和评估指标。模型的训练则需要指定训练集、验证集、批处理大小和训练轮数等参数。可以用以下方式训练和评估模型: ``` history = model.fit(x_train, y_train, batch_size=64, epochs=5, validation_data=(x_val, y_val)) test_scores = model.evaluate(x_test, y_test, verbose=2) print('Test loss:', test_scores[0]) print('Test accuracy:', test_scores[1]) ``` 以上是Keras搭建神经网络的基本流程,需要根据具体问题和数据集的不同进行调整和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值