u1s1,借助tensorflow库编写图像处理的神经网络模型真的十分的简单,感觉十分适合新手入门。随手调用几个函数,一套近乎完美的模型就呈现在我们眼前了。o(≧口≦)o
数据用的是datasets.mnist.load_data()的官方数据。
本文将从数据预处理,模型的结构设置,模型的训练三个板块带你感受tensorflow的魅力。
当然本文最后会给出运行结果及全部代码。♪(´▽`)
参考博客:https://blog.youkuaiyun.com/xiaobian_/article/details/105522596?ops_request_misc=&request_id=&biz_id=102&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0)
数据预处理
数据的预处理十分重要,本文的预处理思路基本分为三步:
1、x,y全部全部转化为张量
2、将x的大小控制在[-1,1]之间,方便转移函数进行训练
3、对y采用one_hot编码,便于提炼出模型训练的特征,并消除数字编码大小带来的影响。
具体代码如下:
# 对数据进行预处理
def pretreatment(x, y):
"""
:param x: 待处理的自变量x
:param y: 待处理的因变量y
:return: 处理完成的的x和y
"""
# 将x转化为张量,并将x的值的大小固定在[-1,1]的区间(转移函数[-1,1]区间内变化明显
x = 2 * tf.convert_to_tensor(x, dtype=tf.float32) / 255 - 1
# 将y转化为张量
y = tf.convert_to_tensor(y, dtype=tf.int32)
# 对y进行one_hot编码,便于提炼出模型特征,并消除数字大小带来的影响
y = tf.one_hot(y, depth=10)
return x, y
模型的结构设置
通过设置隐层并选取正确的转移函数能够更好的对非线性数据进行分类。
本文对输入层到隐层及隐层之间的转移函数默认为relu函数;对于隐层到输出层的转移函数默认为softmax函数以便下文进行训练时采用交叉熵计算误差。
具体代码如下:
# 模型的设置以及隐层的添加
def set_model(size_hidden_layer, num_hidden_layer, size_output_layer, activation_hidden_layer="relu",
activation_output_layer="softmax"):
"""
:param size_hidden_layer: 第一个隐层的元素数量
:param num_hidden_layer: 添加隐层的数量
:param size_output_layer: 输出层的元素的数量
:param activation_hidden_layer: 隐层处理时用的函数
:param activation_output_layer: 输出层处理时的函数
:return: 添加隐层后的模型
"""
# 设置模型
model = keras.Sequential()
# 增加num_hidden_layer个隐层
try:
# 循环增加隐层数量,新增隐层中的元素数量是上一层的1/2
for i in range(num_hidden_layer):
model.add(tf.keras.layers.Dense(size_hidden_layer // (2 * (i + 1)), activation=activation_hidden_layer))
# 设置输出层
model.add(tf.keras.layers.Dense(size_output_layer, activation=activation_output_layer))
# 当输出层的数量小于等于0时抛出异常
if size_output_layer <= 0:
raise Exception("输出层的数量小于等于0")
# 当隐层的数量小于等于0时抛出异常
if size_hidden_layer <= 0:
raise Exception("隐层的数量小于等于0")
except Exception as e:
print(e)
return model
模型的训练
本文将通过adam(优化算法),及交叉熵函数(损失函数)进行模型的训练
具体代码如下::
# 模型处理
def data_processing(model, x, y, epochs, optimization_algorithm="adam", loss_function="categorical_crossentropy"):
"""
:param model: 待处理的模型
:param x: 自变量x
:param y: 因变量y
:param epochs: 训练次数
:param optimization_algorithm: 优化函数,默认为adam
:param loss_function: 损失函数,默认为交叉熵
:return: 训练完成的模型
"""
model.compile(optimizer=optimization_algorithm, loss=loss_function, metrics=['acc'])
model.fit(x, y, epochs=epochs)
return model
运行结果及全部代码
datasets.mnist.load_data()的数据有6w个之多,寻来起来十分费时,因此我们只选择前1000个进行训练及测试。
一定要记得对训练集的x进行预处理,不然看到准确率时,泪会不自觉地留下来இ௰இ
代码如下:
if __name__ == '__main__':
# 获取训练集和测试集
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
x_train = x_train[:1000]
y_train = y_train[:1000]
# print(f"y_train:{y_train},y_test:{y_test}")
# 对训练数据预处理
x_train, y_train = pretreatment(x_train, y_train)
# 对测试数据预处理
x_test, y_test = pretreatment(x_test, y_test)
# 对x进行降维,使之和y在同一纬度
x_train = tf.reshape(x_train, (-1, 28 * 28))
x_test = tf.reshape(x_test, (-1, 28 * 28))
# 设置模型
model = set_model(256, 2, 10)
# 用训练集训练模型
data_processing(model, x_train, y_train, 100)
# 用测试集测试模型
model.evaluate(x_test, y_test)
因为数据过多就只给出训练集最后一次训练及测试集测试的数据
结果如下:
训练集:- 0s 41us/sample - loss: 2.8587e-04 - acc: 1.0000
测试集:- 0s 35us/sample - loss: 0.5062 - acc: 0.8837
全部代码
全部代码如下:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, optimizers, datasets
# 对数据进行预处理
def pretreatment(x, y):
"""
:param x: 待处理的自变量x
:param y: 待处理的因变量y
:return: 处理完成的的x和y
"""
# 将x转化为张量,并将x的值的大小固定在[-1,1]的区间(转移函数[-1,1]区间内变化明显
x = 2 * tf.convert_to_tensor(x, dtype=tf.float32) / 255 - 1
# 将y转化为张量
y = tf.convert_to_tensor(y, dtype=tf.int32)
# 对y进行one_hot编码,便于提炼出模型特征,并消除数字大小带来的影响
y = tf.one_hot(y, depth=10)
return x, y
# 模型的设置以及隐层的添加
def set_model(size_hidden_layer, num_hidden_layer, size_output_layer, activation_hidden_layer="relu",
activation_output_layer="softmax"):
"""
:param size_hidden_layer: 第一个隐层的元素数量
:param num_hidden_layer: 添加隐层的数量
:param size_output_layer: 输出层的元素的数量
:param activation_hidden_layer: 隐层处理时用的函数
:param activation_output_layer: 输出层处理时的函数
:return: 添加隐层后的模型
"""
# 设置模型
model = keras.Sequential()
# 增加num_hidden_layer个隐层
try:
# 循环增加隐层数量,新增隐层中的元素数量是上一层的1/2
for i in range(num_hidden_layer):
model.add(tf.keras.layers.Dense(size_hidden_layer // (2 * (i + 1)), activation=activation_hidden_layer))
# 设置输出层
model.add(tf.keras.layers.Dense(size_output_layer, activation=activation_output_layer))
# 当输出层的数量小于等于0时抛出异常
if size_output_layer <= 0:
raise Exception("输出层的数量小于等于0")
# 当隐层的数量小于等于0时抛出异常
if size_hidden_layer <= 0:
raise Exception("隐层的数量小于等于0")
except Exception as e:
print(e)
return model
# 模型处理
def data_processing(model, x, y, epochs, optimization_algorithm="adam", loss_function="categorical_crossentropy"):
"""
:param model: 待处理的模型
:param x: 自变量x
:param y: 因变量y
:param epochs: 训练次数
:param optimization_algorithm: 优化函数,默认为adam
:param loss_function: 损失函数,默认为交叉熵
:return: 训练完成的模型
"""
model.compile(optimizer=optimization_algorithm, loss=loss_function, metrics=['acc'])
model.fit(x, y, epochs=epochs)
return model
if __name__ == '__main__':
# 获取训练集和测试集
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
x_train = x_train[:1000]
y_train = y_train[:1000]
# print(f"y_train:{y_train},y_test:{y_test}")
# 对训练数据预处理
x_train, y_train = pretreatment(x_train, y_train)
# 对测试数据预处理
x_test, y_test = pretreatment(x_test, y_test)
# 对x进行降维,使之和y在同一纬度
x_train = tf.reshape(x_train, (-1, 28 * 28))
x_test = tf.reshape(x_test, (-1, 28 * 28))
# 设置模型
model = set_model(256, 2, 10)
# 用训练集训练模型
data_processing(model, x_train, y_train, 100)
# 用测试集测试模型
model.evaluate(x_test, y_test)