方法一
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#准备数据,26M
#训练模型,保存模型
# fashion_mnist = tf.keras.datasets.fashion_mnist
# (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
class FashionMnistLoader():
def __init__(self):
mnist = tf.keras.datasets.fashion_mnist
(self.train_data, self.train_label), (self.test_data, self.test_label) = mnist.load_data()
#MNIST中的图像默认为uint8(0-255的数字)。以下代码将其归一化到0-1之间的浮点数,并在最后增加一维作为颜色通道
self.train_data = np.expand_dims(self.train_data.astype(np.float32)/255.0, axis=-1) # [60000, 28, 28, 1]#在最后位置,增加一维度,与reshape类似
self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1) # [10000, 28, 28, 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):
#生产随机索引
index = np.random.randint(0, self.num_train_data, batch_size)
#根据随机索引返回对应内容
return self.train_data[index, :], self.train_label[index] #随机获取50条数据
#载入数据
data_loader = FashionMnistLoader()
# plt.figure(figsize=(10,10)) #画布大小
# for i in range(25):
# plt.subplot(5, 5, i+1) #5行5列,第i+1位置
# plt.xticks([])
# plt.yticks([])
# plt.imshow(data_loader.train_data[i], cmap=plt.cm.binary)
# plt.xlabel(class_names[data_loader.train_label[i]])
# plt.show()
#超参数
num_epochs = 5 #循环5次
batch_size = 50 #每次读取的数据量
learning_rate = 0.001 #学习率,很重要
def create_model():
# 构建模型,Sequential方式
model = tf.keras.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)), # 将图像格式从二维数组(28 x 28 像素)转换成一维数组(28 x 28 = 784 像素)
tf.keras.layers.Dense(128, activation='relu'), # 它们是密集连接或全连接神经层。第一个 Dense 层有 128 个节点(或神经元)
tf.keras.layers.Dense(10) # 第二个(也是最后一个)层会返回一个长度为 10 的 logits 数组
])
# 编译模型,进行相关设置,包括损失函数,优化器,指标等
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
return model
#创建模型
model = create_model()
#保存模型,方便下次使用
checkpoint = 'training.ckpt'
checkpoint_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint, save_weights_only=True, verbose=1)
#训练模型
model.fit(data_loader.train_data, data_loader.train_label, epochs=10, callbacks=checkpoint_callback)
#评估模型
test_loss, test_acc = model.evaluate(data_loader.test_data, data_loader.test_label, verbose=2)
print('Test accuracy:', test_acc) #Test accuracy: 0.8765000104904175
#使用模型,预测
prob_model = tf.keras.Sequential([model, tf.keras.layers.Softmax()])
pred = prob_model.predict(data_loader.test_data)
print(np.argmax(pred[0])) #最大值即为预测的分类
#画图查看,更直观
def plot_image(i, predictions_array, true_label, img):
true_label, img = true_label[i], img[i]
plt.grid(False)
plt.xticks([])
plt.yticks([])
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array)
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color)
def plot_value_array(i, predictions_array, true_label):
true_label = true_label[i]
plt.grid(False)
plt.xticks(range(10))
plt.yticks([])
thisplot = plt.bar(range(10), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
#画图
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
plt.subplot(num_rows, 2*num_cols, 2*i+1)
plot_image(i, pred[i], data_loader.test_label, data_loader.test_data)
plt.subplot(num_rows, 2*num_cols, 2*i+2)
plot_value_array(i, pred[i], data_loader.test_label)
plt.tight_layout()
plt.show()
#在工程中应用模型:
checkpoint = 'training.ckpt' #在工程化时主要就是使用已训练好的模型
#创建模型
model = create_model()
#load 训练好的参数
model.load_weights(checkpoint)
#载入数据
data_loader = FashionMnistLoader()
#使用模型,预测
prob_model = tf.keras.Sequential([model, tf.keras.layers.Softmax()])
pred = prob_model.predict(data_loader.test_data)
print(np.argmax(pred[2])) #最大值即为预测的分类
方法二,优化参数
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
#准备数据,26M
#训练模型,优化模型,推荐
# fashion_mnist = tf.keras.datasets.fashion_mnist
# (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
class FashionMnistLoader():
def __init__(self):
mnist = tf.keras.datasets.fashion_mnist
(self.train_data, self.train_label), (self.test_data, self.test_label) = mnist.load_data()
#MNIST中的图像默认为uint8(0-255的数字)。以下代码将其归一化到0-1之间的浮点数,并在最后增加一维作为颜色通道
self.train_data = np.expand_dims(self.train_data.astype(np.float32)/255.0, axis=-1) # [60000, 28, 28, 1]#在最后位置,增加一维度,与reshape类似
self.test_data = np.expand_dims(self.test_data.astype(np.float32) / 255.0, axis=-1) # [10000, 28, 28, 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):
#生产随机索引
index = np.random.randint(0, self.num_train_data, batch_size)
#根据随机索引返回对应内容
return self.train_data[index, :], self.train_label[index] #随机获取50条数据
#推荐写法, 个人不喜欢tf.keras.Sequential
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
self.conv1 = tf.keras.layers.Conv2D(32, 3, activation='relu')
self.flatten = tf.keras.layers.Flatten() #必须是tf.keras.layers这个包,不要调错了
self.d1 = tf.keras.layers.Dense(128, activation='relu')
self.d2 = tf.keras.layers.Dense(10)
def call(self, x):
x = self.conv1(x)
x = self.flatten(x)
x = self.d1(x)
return self.d2(x)
class CNN(tf.keras.Model):
# 初始化
def __init__(self):
super().__init__()
#第一层卷积
self.conv1 = tf.keras.layers.Conv2D(
filters=32, #卷积层神经元(卷积核)数目,设置神经元(卷积核)数目32,则输出(batchsize,28,28,32),32个神经元输出数据整合到一起
kernel_size=[5,5], #感受野大小,卷积核大小,就是那个小方块的大小,通常为奇数正方形,比如3*3,5*5
padding='same', # padding策略(vaild 或 same)
activation=tf.nn.relu #激活函数
)
#加一个池化层,用区域最大值池化,本质也是降维
self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2,2],strides=2)
#第二层卷积
self.conv2 = tf.keras.layers.Conv2D(
filters=64, # 卷积层神经元(卷积核)数目,这个数据是啥?
kernel_size=[5, 5], # 感受野大小,卷积核大小,就是那个小方块的大小,通常为奇数正方形,比如3*3,5*5
padding='same', # padding策略(vaild 或 same)
activation=tf.nn.relu # 激活函数
)
#再池化一次
self.pool2 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
#压平,就是resharp
self.flatten = tf.keras.layers.Reshape(target_shape=(7 * 7 * 64,))
#全连接层,输出1024
self.dense1 = tf.keras.layers.Dense(units=1024, activation=tf.nn.relu)
#全连接层,输出10,10就是最终输出各分类的概率
self.dense2 = tf.keras.layers.Dense(units=10)
#call什么时候被调用?
def call(self, inputs): #输入数据[batch_size,28,28,1]
print("call......")
x = self.conv1(inputs) # [batch_size, 28, 28, 32]
x = self.pool1(x) # [batch_size, 14, 14, 32]
x = self.conv2(x) # [batch_size, 14, 14, 64]
x = self.pool2(x) # [batch_size, 7, 7, 64]
x = self.flatten(x) # [batch_size, 7 * 7 * 64]
x = self.dense1(x) # [batch_size, 1024]
x = self.dense2(x) # [batch_size, 10]
output = tf.nn.softmax(x) #取出最大概率的那个分类
return output
#载入数据
data_loader = FashionMnistLoader()
# plt.figure(figsize=(10,10)) #画布大小
# for i in range(25):
# plt.subplot(5, 5, i+1) #5行5列,第i+1位置
# plt.xticks([])
# plt.yticks([])
# plt.imshow(data_loader.train_data[i], cmap=plt.cm.binary)
# plt.xlabel(class_names[data_loader.train_label[i]])
# plt.show()
#超参数
num_epochs = 5 #循环5次
batch_size = 50 #每次读取的数据量
learning_rate = 0.001 #学习率,很重要
#模型
# model = MyModel() #准确率99%
model = CNN()
#优化,Adam代替了GD梯度算法
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
#一共循环的次数 1200 * 5
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)
#损失函数,交叉熵作为损失函数,代替了MSE,在分类问题中被广泛应用。其离散形式为 H(y, \hat{y}) = -\sum_{i=1}^{n}y_i \log(\hat{y_i}) ,其中 y 为真实概率分布, \hat{y} 为预测概率分布, n 为分类任务的类别个数。预测概率分布与真实分布越接近,则交叉熵的值越小,反之则越大。
loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=y, y_pred=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)) #应用优化
print("final variables", model.variables)
model.summary() #训练完之后,才能调用
checkpoint = 'training.ckpt'
model.save_weights(checkpoint)
#模型的评估
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()))
#准确率只有0.9
2万+

被折叠的 条评论
为什么被折叠?



