本文主要针对优达学城深度学习课程中的练习题,整理练习内容,有兴趣者可结合本文内容然后按练习题实践,帮助理解。
任务主要完成图片下载、图片内容数字化、选取三个数据集、打乱顺序、持久化数据等,步骤如下:
large与small不止数量大小区别,还在于large中的图片有没经过人工筛选,有噪点以及损坏图片,从中选取数据作为训练集与验证集,small中的图片经过人工筛选,数据相对干净,从中选取数据作为测试集
每张图片可以用一个
28 x 28
的二维数组表示,一个目录下的n张图片放到一个n x 28 x 28
的三维数组中,然后通过pickle序列化到文件中
从处理好的数据中选取训练集、验证集、测试集,选取过程中每个类别打乱顺序并合并不同类别,同时使用数组记录每个数据项对应的类别(label)
针对每个数据集与label,再次打乱顺序,然后把所有数据集以及相应label包装成dict序列化到磁盘
使用sklearn.linear_model中的LogisticRegression模型训练一个模型,主要代码:
import numpy as np
import pickle
from sklearn.linear_model import LogisticRegression
image_size = 28
train_size = 1000
data = pickle.load(open('notMNIST.pickle','rb'))
train_features = data['train_dataset'][:train_size]
train_labels = data['train_labels'][:train_size]
test_features = data['test_dataset']
test_labels = data['test_labels']
train_features = train_features.reshape(len(train_features), image_size * image_size)
test_features = test_features.reshape(len(test_features), image_size * image_size)
print 'start train!'
classifier = LogisticRegression()
classifier.fit(train_features, train_labels)
print 'start predict!'
score = classifier.score(test_features,test_labels)
print 'The accuray score is %.3f' % score
结果:
start train!
start predict!
The accuray score is 0.828
任务主要构造TF计算图、训练模型,最后验证随机梯度下降算法带来的速度优化,这部分内容比上一个任务难度增加,开始涉及TF编程,分为以下几步:
将特征数组由
n x 28 x 28
的变形为n x 784
,label的值使用One-Hot编码
选取了部分训练数据作为输入,使用tf.truncated_normal生成权重矩阵,计算输入矩阵与权重矩阵的乘积再加上偏差,然后计算softmax和交叉熵,并使用所有样本的交叉熵平均值作为模型针对样本的损失值,最后使用梯度下降算法优化器优化模型
训练801步,每训练100步,输出模型针对训练集与验证集的损失值、准确度
重新构造计算图,然后使用随机梯度下降算法训练3001步,训练速度比普通梯度下降算法更快
任务二下面有留下一个需要解答的问题:“添加一层通过ReLU函数激活的隐藏层”,主要代码如下:
batch_size = 128
hidden_layer_node_num = 1024
graph = tf.Graph()
with graph.as_default():
tf_train_dataset = tf.placeholder(tf.float32, shape=(batch_size, image_size * image_size))
tf_train_labels = tf.placeholder(tf.float32, shape=(batch_size, num_labels))
tf_valid_dataset = tf.constant(valid_dataset)
tf_test_dataset = tf.constant(test_dataset)
hidden_weights = tf.Variable(tf.truncated_normal([image_size * image_size, hidden_layer_node_num]))
hidden_biases = tf.Variable(tf.zeros([hidden_layer_node_num]))
weights = tf.Variable(tf.truncated_normal([hidden_layer_node_num, num_labels]))
biases = tf.Variable(tf.zeros([num_labels]))
logits = tf.matmul(tf.nn.relu(tf.matmul(tf_train_dataset, hidden_weights) + hidden_biases), weights) + biases
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=tf_train_labels, logits=logits))
optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
train_prediction = tf.nn.softmax(logits)
valid_prediction = tf.nn.softmax(tf.matmul(tf.nn.relu(tf.matmul(tf_valid_dataset, hidden_weights) + hidden_biases), weights) + biases)
test_prediction = tf.nn.softmax(tf.matmul(tf.nn.relu(tf.matmul(tf_test_dataset, hidden_weights) + hidden_biases), weights) + biases)
任务三本身没有多少现成代码,主要靠自己动手。
接任务二ReLU的代码,只要为损失函数loss添加L2正则化的结果即可,选0.001438作为超参λ的值,课程没有讲如何选择超参的值,这个值是从他人文章中借用的。
在之前的损失函数赋值后面添加:
loss = loss + 0.001438 * (tf.nn.l2_loss(hidden_weights) + tf.nn.l2_loss(hidden_biases) + tf.nn.l2_loss(weights) + tf.nn.l2_loss(biases))
将训练数据减少为几个批次的量,演示过度拟合。
从训练数据中取出一个较小的子集作为训练集:
batch_size = 128
train_dataset = train_dataset[:batch_size * 5, :]
train_labels = train_labels[:batch_size * 5, :]
过度拟合,会导致模型在训练集上的表现很好,但针对验证集或测试集,表现大打折扣。
dropout会随机将输入值丢弃或缩放,可达到训练模型冗余性,防止过度拟合。
核心代码:
tmp = tf.nn.relu(tf.matmul(tf_train_dataset, hidden_weights) + hidden_biases)
tmp = tf.nn.dropout(tmp, 0.5)
logits = tf.matmul(tmp, weights) + biases
dropout第二个参数0.5,说明dropout的行为是随机将部分值置为0,另外一部分x2,这样,整体样本的平均值不会变化。
该习题的目的是使用多层神经网络,使最终测试集的准确率达到97.1%。
核心代码:
hlnn1 = 4096
hlnn2 = 2048
hlnn3 = 128
hw1 = tf.Variable(tf.truncated_normal([image_size * image_size, hlnn1], stddev=np.sqrt(2.0 / (image_size * image_size))))
hb1 = tf.Variable(tf.zeros([hlnn1]))
hw2 = tf.Variable(tf.truncated_normal([hlnn1, hlnn2], stddev=np.sqrt(2.0 / hlnn1)))
hb2 = tf.Variable(tf.zeros([hlnn2]))
hw3 = tf.Variable(tf.truncated_normal([hlnn2, hlnn3], stddev=np.sqrt(2.0 / hlnn2)))
hb3 = tf.Variable(tf.zeros([hlnn3]))
weights = tf.Variable(tf.truncated_normal([hlnn3, num_labels], stddev=np.sqrt(2.0 / hlnn3)))
biases = tf.Variable(tf.zeros([num_labels]))
tmp = tf.nn.relu(tf.matmul(tf_train_dataset, hw1) + hb1)
tmp = tf.nn.relu(tf.matmul(tmp, hw2) + hb2)
tmp = tf.nn.relu(tf.matmul(tmp, hw3) + hb3)
logits = tf.matmul(tmp, weights) + biases
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=tf_train_labels, logits=logits))
loss = loss + tf_beta * (tf.nn.l2_loss(hw1) + tf.nn.l2_loss(hb1) + tf.nn.l2_loss(hw2) + tf.nn.l2_loss(hb2) +
tf.nn.l2_loss(hw3) + tf.nn.l2_loss(hb3) + tf.nn.l2_loss(weights) + tf.nn.l2_loss(biases))
learning_rate = tf.train.exponential_decay(0.5, global_step, 1000, 0.7, staircase=True)
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
添加多个隐藏层,然后使用学习速率衰减方式,让损失降低,准确率进一步提升,到这一步我的Mac电脑已经开始吃不消,训练5000步,模型在测试集上的准确率95.1%,继续训练,模型的表现应该会更好。
博客原文