tensorflow2.0更普遍的构建模型
在tensorflow2.0里面,最典型和常用的神经网络结构是将一堆层按特定顺序叠加起来,那么,我们是不是只需要提供一个层的列表,就能由 Keras 将它们自动首尾相连,形成模型呢?Keras 的 Sequential API 正是如此。通过向 tf.keras.models.Sequential() 提供一个层的列表,就能快速地建立一个 tf.keras.Model 模型并返回,就如我之前写到的博客一样。
但这种的写法和其他流行的深度学习的框架(如PyTorch)不能很好的贯通,灵活性也不是很高,比较适合搭建一个相对简单或者是比较典型的神经网络(例如CNN,MLP)
下面就以一个mnist数据集来看看这种用类继承的方式怎么搭建一个神经网络。
#先把数据集引入
class MnistLoader():
def __init__(self):
mnist = tf.keras.datasets.mnist
(self.train_data, self.train_label), (self.test_data, self.test_label) = mnist.load_data()
'''
对数据集归一化,并加一个通道来输入颜色,由于这里读入的是灰度图片,
色彩通道数为 1(彩色 RGB 图像色彩通道数为 3),所以我们使用
np.expand_dims() 函数为图像数据手动在最后添加一维通道。
'''
self.train_data = np.expand_dims(self.train_data.astpye(np.float32)/255.0.axis = -1)
self.test_data = np.expand_dims(self.test_data.astpye(np.float32)//255.0,axis = -1)
self.train_label = self.train_label.astype(np.int32) # [60000]
self.test_label = self.test_label.astype(np.int32) # [10000]
self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]
def get_batch(self, batch_size):
# 从数据集中随机取出batch_size个元素并返回
index = np.random.randint(0, np.shape(self.train_data)[0], batch_size)
return self.train_data[index, :], self.train_label[index]
下面就是通过类的继承来搭建一个数据集
class MLP(tf.keras.Model):
def __init__(self):
super().__init__()
self.flatten = tf.keras.layers.Flatten() # Flatten层将除第一维(batch_size)以外的维度展平
self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)
#注意这里的**函数relu和之前的写法不一样
self.dense2 = tf.keras.layers.Dense(units=10)
def call(self,inputs):
x1 = self.flatten(inputs)
x2 = self.dense1(x1)
x3 = self.dense2(x2)
output = tf.nn.softmax(x3)
return output
为了使得模型的输出能始终满足这两个条件,我们使用 Softmax 函数 (归一化指数函数, tf.nn.softmax )对模型的原始输出进行归一化。不仅如此,softmax 函数能够凸显原始向量中最大的值,并抑制远低于最大值的其他分量,这也是该函数被称作 softmax 函数的原因(即平滑化的 argmax 函数)。
输出的形式大致是[0.001,0.02,0.93,…,0.003]把十种分类的可能概率输出出来
接下里就是定义一些超参数和实例化的过程
batch_size = 50
epochs = 5
learning_rata = 0.001
data_load = MnistLoader()
model = MLP()
optimizer = tf.keras.optimizers.Adam(learning_rata = learning_rata)
接下里就是计算出损失函数,开始训练模型
num_batches = int(data_loader.num_train_data // batch_size * num_epochs)
for batch_index in range(num_batches):
x, y = data_loader.get_batch(batch_size)
with tf.GradientTape() as tape:
y_pred = model(X)
loss = tf.keras.losses.sparse_categorical_crossentropy(y_true = y , y_predict = y_pred)
loss = tf.reduce_mean(loss)
print("batch %d: loss %f" % (batch_index, loss.numpy()))
#算梯度
grads = tape.gradient(loss, model.variables)
#调参
optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
这一块的内容如果有看不懂的,可以看我之前的博客,tensorflow基础,里面有详细的解释。
最后就是对我们的模型进行评估
#我们用tf.keras.metrics
sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
num_batches = int(data_loader.num_test_data // batch_size)
for batch_index in range(num_batches):
start_index, end_index = batch_index * batch_size, (batch_index + 1) * batch_size
y_pred = model.predict(data_loader.test_data[start_index: end_index])
sparse_categorical_accuracy.update_state(y_true=data_loader.test_label[start_index: end_index], y_pred=y_pred)
print("test accuracy: %f" % sparse_categorical_accuracy.result())
最后,我们使用测试集评估模型的性能。这里,我们使用 tf.keras.metrics 中的 SparseCategoricalAccuracy 评估器来评估模型在测试集上的性能,该评估器能够对模型预测的结果与真实结果进行比较,并输出预测正确的样本数占总样本数的比例。我们迭代测试数据集,每次通过 update_state() 方法向评估器输入两个参数: y_pred 和 y_true ,即模型预测出的结果和真实结果。评估器具有内部变量来保存当前评估指标相关的参数数值(例如当前已传入的累计样本数和当前预测正确的样本数)。迭代结束后,我们使用 result() 方法输出最终的评估指标值(预测正确的样本数占总样本数的比例)。
在以下代码中,我们实例化了一个 tf.keras.metrics.SparseCategoricalAccuracy 评估器,并使用 For 循环迭代分批次传入了测试集数据的预测结果与真实结果,并输出训练后的模型在测试数据集上的准确率。
上一篇: tensorflow基本使用
下一篇: jquery选择器