本文介绍了以下内容:
(1)tf和pytorch搭建网络架构的两种方法。即采用sequential容器,采用构建器构建或者采用add方法构建。
(2)模型编译过程:model.compile()
(3)模型训练过程:model.fit()
(4)模型评估和使用:model.evaluate()和model.predict()
一、模型搭建概述
1. 搭建过程
2. 搭建方法
二、Pytorch搭建网络模型
1. 构建器
2. 采用add_module()方法
三、tensorflow的keras搭建网络模型
1. 构建网络模型
2. 确定模型中数据规格
四、模型编译
五、模型训练
六、模型评估和使用
1. 模型评估
2. 模型使用
七、实例
搭建神经网络主要有两个库,一个是pytorch,一个是tensorflow(中的keras),两个都是很常用的方法。
搭建神经网络架构的方法有很多种,比如自己写函数搭建,更多的是使用sequential类搭建。
完成一个模型搭建,大概需要三个步骤:创建网络->模型编译->模型训练。
(1)创建网络:创建网络即使用sequential类搭建网络模型的过程,也是我们要讲的重点。即使用sequential类将卷积层,RNN层,全连接层等搭建起来,加上激活函数,说明每层的参数;
(2)模型编译:调用model.compile()函数,一般使用三个组件,模型优化器,损失函数和模型评估标准;
(3)模型训练:调用model.fit()函数,对模型进行训练,一般使用四个参数:特征数据data,标签label,迭代次数epoch,批次大小batchsize。
有时还使用model.calculate()进行评估。
本文主要介绍使用sequential容器进行模型搭建。
主要有两种方法,
(1)第一种直接使用构建器torch.nn.Sequential()或者tf.keras.models.Sequential容器进行快速搭建。构建起搭建时,将每层顺序写下去即可。如果需要给每层命名的话,通过字典的形式添加每一层即可。
(2)采用add方法
对于pytorch来说,可以采用add_module()添加每一层;对于tf,可以通过model.add()方法添加每一层。同时add方法可以给每层命名。
model=torch.nn.Sequential(
torch.nn.Conv2d(3, 32, 3, 1, 1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(2))
torch.nn.Linear(32 * 3 * 3, 128),
torch.nn.ReLU(),
torch.nn.Linear(128, 10)
)
添加每层的名称时,改用字典传入有序模块:
model = torch.nn.Sequential(OrderedDict([
('conv1', torch.nn.Conv2d(1,20,5)),
('relu1', torch.nn.ReLU()),
('conv2', torch.nn.Conv2d(20,64,5)),
('relu2', torch.nn.ReLU())
]))
model=torch.nn.Sequential()
model.add_module("conv1",torch.nn.Conv2d(3, 32, 3, 1, 1))
model.add_module("relu1",torch.nn.ReLU())
model.add_module("pool1",torch.nn.MaxPool2d(2))
model.add_module("dense1",torch.nn.Linear(32 * 3 * 3, 128))
model.add_module("relu2",torch.nn.ReLU())
model.add_module("dense2",torch.nn.Linear(128, 10))
通过sequential类可快速堆叠出一个网络模型。
两种方法,第一种构建构造器,第二种通过add方法。
(1)构建器构建
直接定义一个构建器,然后在里边顺序添加网络层即可。
model = tf.keras.Sequential([
tf.keras.layers.Dense(32, input_shape=(784,)),
tf.keras.layers.Activation('relu'),
tf.keras.layers.Dense(10),
tf.keras.layers.Activation('softmax'),
])
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28,28)),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10,activation='softmax')
])
(2)add方法构建
定义一个sequential类,赋值给model,然后采用model.add()方法,顺序添加网络层。
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(32, input_dim=784))
model.add(tf.keras.layers.Activation('relu'))
keras中只有第一层需要通过参数传递方式确定数据规格,其他层都是通过推导获得上一层的输出格式和下一层的输入格式。
(1)通过input_shape参数,如input_shape=(784,)
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(32, input_shape=(784,)))
(2)通过input_dim参数,在二维神经网络层中,也可通过input_dim=784的方式实现类似(1)的定义
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(32, input_dim=784))
模型编译调用model.compile()函数实现。
可以使用compile(self, optimizer, loss, metrics=None, sample_weight_mode=None, weighted_metrics=None, target_tensors=None)来完成配置。
主要节后前三个参数:优化器、损失函数、模型评估标准。
(1)优化器(optimizer):字符串类型,用来指定优化方式,如:rmsprop,adam,sgd;
(2)损失函数(loss):字符串类型,用来指定损失函数,如:categorical_crossentropy,binary_crossentropy;
(3)评估标准(metrics):列表类型,用来指定衡量模型的指标,如:accuracy。
# 多分类问题
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 二分类问题
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
# 均方误差回归问题
model.compile(optimizer='rmsprop',
loss='mse')
# 自定义评估标准函数
def mean_pred(y_true, y_pred):
return tf.keras.backend.mean(y_pred)
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy', mean_pred])
调用model.fit()函数,对模型进行训练。一般需要设置特征数据(x_test),label(y_test),epoch,batchsize等参数。
fit(self, x, y, batch_size=32, epochs=10, verbose=1,
callbacks=None, validation_split=0.0,
validation_data=None, shuffle=True,
class_weight=None, sample_weight=None,
initial_epoch=0)
同时,model.fit函数返回的是一个history类型的数据,可以通过History.history来查看训练过程,比如模型训练时训练集loss、验证集loss、训练集准确率数据(随epoch的变化情况),作为字典保存了下来。
但不同方法种调用loss和acc的数据不一样,如:
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
以下进行举例:
(1)二分类:
# 对于具有 2 个类的单输入模型(二进制分类):
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(32, activation='relu', input_dim=100))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
# 生成虚拟数据
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))
# 训练模型,以 32 个样本为一个 batch 进行迭代
model.fit(data, labels, epochs=10, batch_size=32)
(2)多分类:
# 对于具有 10 个类的单输入模型(多分类分类):
model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(32, activation='relu', input_dim=100))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 生成虚拟数据
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(10, size=(1000, 1))
# 将标签转换为分类的 one-hot 编码
one_hot_labels = tf.keras.utils.to_categorical(labels, num_classes=10)
# 训练模型,以 32 个样本为一个 batch 进行迭代
model.fit(data, one_hot_labels, epochs=10, batch_size=32)
模型训练完之后,可以保存下来,使用model.evaluate()使用测试集数据对模型进行评估。
同时也可以开始使用,通过model.predict()对数据进行预测。
使用model.evaluate()方法进行评估,返回的是损失值loss和你指定的指标值(在模型编译时第三个参数:模型评估标准,即metric()里的参数)。比如你的目标是准确率accuracy,即model.compile(metric["accuracy"])。此处返回测试集的Loss和acc。只返回一个最终值。
test_loss,test_acc = model.evaluate(test_images,test_labels,verbose=1)
使用model.predict()方法将测试集照片进行预测,传入的是测试集数据,输出的是一个列表,保存对每个对应的test_images的预测。一般为二维。
比如在10分类问题中,每个预测结果predict[i]都是一个长度为10的一维数组(十分类问题),哪个值最大就属于哪个分类结果。所以predeicts是一个test_size*10的二维数组。
ppredictions = model.predict(test_images)
for i in range(10):
print('预测值 = %i;正确值 = %i' % (np.argmax(predictions[i]),test_labels[i]))
1. 采用model.add方法搭建的CNN网络对二维图像数据进行分类:
import numpy as np
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout,Flatten,Conv2D,MaxPooling2D
from tensorflow.keras.optimizers import SGD
# 生成虚拟数据
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
x_test = np.random.random((20, 100, 100, 3))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(20, 1)), num_classes=10)
model = Sequential()
# 输入: 3 通道 100x100 像素图像 -> (100, 100, 3) 张量。
# 使用 32 个大小为 3x3 的卷积滤波器。
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
#Flatten对特征进行扁平化处理
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)
model.fit(x_train, y_train, batch_size=32, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=32)