首页 > Udacity机器人软件工程师课程笔记(二十八) - 卷积神经网络实例 - Fashion-MNIST数据集

Udacity机器人软件工程师课程笔记(二十八) - 卷积神经网络实例 - Fashion-MNIST数据集

1.Fashion-MNIST数据集

Fashion-MNIST数据集包括一个包含60,000个示例的训练集和一个包含10,000个示例的测试集。每个示例是一个28x28灰度图像,与来自以下10个类的标签相关联:

  • T恤/上衣
  • 裤子
  • 套衫
  • 连衣裙
  • 外套
  • 凉鞋
  • 衬衫
  • 运动鞋
  • 短靴



    Source: https://github.com/zalandoresearch/fashion-mnist/

由于给的样例是.ipynb格式的,因为我习惯使用pycharm,因此我将程序改到.py格式,但是由于内容较多,只能一点一点来研究相关程序。

2.cnn_preprocess.py

这个程序预处理数据,给神经网络提供训练数据。


(1)探索数据

import helper
import numpy as np
# 模块 pickle 实现了对一个 Python 对象结构的二进制序列化和反序列化。
# 这里用来读取fashion-mnist.p程序
import picklefilename = "fashion-mnist.p"sample_id = 17
helper.display_stats(filename, sample_id)

这是helper.py中的程序:

def _load_label_names():"""从文件中加载标签名称"""return ['t-shirt', 'trouser', 'pullover', 'dress', 'coat', 'sandal', 'shirt', 'sneaker', 'bag', 'ankle_boot']def load_dataset(dataset_folder_path):"""加载训练和测试数据集"""with open(dataset_folder_path, mode='rb') as file:pickle_data = pickle.load(file)# 整理训练和测试数据train_features = pickle_data[0].reshape((len(pickle_data[0]), 1, 28, 28)).transpose(0, 2, 3, 1)train_labels = pickle_data[1]test_features = pickle_data[2].reshape((len(pickle_data[2]), 1, 28, 28)).transpose(0, 2, 3, 1)test_labels = pickle_data[3]   return train_features, train_labels, test_features, test_labelsdef display_stats(dataset_folder_path, sample_id):"""显示数据集的状态"""train_features, train_labels, test_features, test_labels = load_dataset(dataset_folder_path)if not (0 <= sample_id < len(train_features)):print('{} samples in training set.  {} is out of range.'.format(len(train_features), sample_id))return Noneprint('Samples: {}'.format(len(train_features)))# 用于统计相关标签数据print('Label Counts: {}'.format(dict(zip(*np.unique(train_labels, return_counts=True)))))print('First 20 Labels: {}'.format(train_labels[:20]))sample_image = train_features[sample_id]sample_label = train_labels[sample_id]label_names = _load_label_names()print('
Example of Image {}:'.format(sample_id))print('Image - Min Value: {} Max Value: {}'.format(sample_image.min(), sample_image.max()))print('Image - Shape: {}'.format(sample_image.shape))print('Label - Label Id: {} Name: {}'.format(sample_label, label_names[sample_label]))plt.axis('off')plt.imshow(sample_image.squeeze(), cmap="gray")plt.show()

输出如下:

Samples: 60000
Label Counts: {0: 6000, 1: 6000, 2: 6000, 3: 6000, 4: 6000, 5: 6000, 6: 6000, 7: 6000, 8: 6000, 9: 6000}
First 20 Labels: [9 0 0 3 0 2 7 2 5 5 0 9 5 5 7 9 1 0 6 4]Example of Image 17:
Image - Min Value: 0 Max Value: 254
Image - Shape: (28, 28, 1)
Label - Label Id: 0 Name: t-shirt

在这里插入图片描述


(2)数据预处理

实现normalize函数以获取图像数据x,并将其作为归一化的Numpy数组返回。值应在0到1范围内。返回对象的形状应与x相同。

import problem_unittests as tests
def normalize(x):"""将0到1范围内的样本图像数据列表进行规范化"""# TODO: Implement Functionoutput = np.array([image/255 for image in x])return output

(3)one-hot码

实现该one_hot_encode功能。输入,x是标签列表。实现该功能以将标签列表作为One-Hot编码的Numpy数组返回。标签的可能值为0到9。“one-hot code”功能应在每次调用one_hot_encode之间为每个值返回相同的编码。

def one_hot_encode(x):"""一个独热码的样本标签列表。为每个标签返回一个独热码向量。"""# TODO: Implement Functionone_hot = np.eye(10)[x]return None

(4)预处理和保存

预处理所有数据,并将其保存,是由10%的训练数据进行验证。

def _preprocess_and_save(normalize, one_hot_encode, features, labels, filename):"""对数据进行预处理并保存到文件中"""features = normalize(features)labels = one_hot_encode(labels)pickle.dump((features, labels), open(filename, 'wb'))def preprocess_and_save_data(dataset_folder_path, normalize, one_hot_encode):"""预处理训练和验证数据"""valid_features = []valid_labels = []train_features, train_labels, test_features, test_labels = load_dataset(dataset_folder_path)validation_count = int(len(train_features) * 0.1)# 对新的培训数据进行预处理和保存_preprocess_and_save(normalize,one_hot_encode,train_features[:-validation_count],train_labels[:-validation_count],'preprocess_train' + '.p')# 使用部分训练batch进行验证valid_features.extend(train_features[-validation_count:])valid_labels.extend(train_labels[-validation_count:])# 对所有验证数据进行预处理和保存_preprocess_and_save(normalize,one_hot_encode,np.array(valid_features),np.array(valid_labels),'preprocess_validation.p')# 对所有测试数据进行预处理和保存_preprocess_and_save(normalize,one_hot_encode,np.array(test_features),np.array(test_labels),'preprocess_test.p')

完整cnn_preprocess.py程序

import helper
import numpy as np
import problem_unittests as tests
import picklefilename = "fashion-mnist.p"def normalize(x):"""将0到1范围内的样本图像数据列表进行归一化"""output = np.array([image / 255 for image in x])return outputdef one_hot_encode(x):"""一个独热码的样本标签列表。为每个标签返回一个独热码向量。"""one_hot = np.eye(10)[x]return one_hot# 对所有数据进行预处理
helper.preprocess_and_save_data(filename, normalize, one_hot_encode)

3.cnn_train.py

import helper
import numpy as np
import problem_unittests as tests
import pickle
import tensorflow as tfdef neural_net_image_input(image_shape):"""返回一批图像输入的张量"""input_image = tf.placeholder(tf.float32, shape=(None, *image_shape), name="x")return input_imagedef neural_net_label_input(n_classes):"""返回一个batch标签输入的张量"""input_label = tf.placeholder(tf.int32, shape=(None, n_classes), name="y")return input_labeldef neural_net_keep_prob_input():"""返回一个保持概率的张量"""keep_prob = tf.placeholder(tf.float32, name="keep_prob")return keep_probdef conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides):"""对x_张量应用卷积和最大池化"""filter_size = [conv_ksize[0], conv_ksize[1], x_tensor.get_shape().as_list()[3], conv_num_outputs]weight = tf.Variable(tf.truncated_normal(filter_size, stddev=0.01))conv = tf.nn.conv2d(x_tensor, weight, [1, conv_strides[0], conv_strides[1], 1], padding="SAME")bias = tf.Variable(tf.zeros([conv_num_outputs]))conv = tf.nn.bias_add(conv, bias)conv = tf.nn.relu(conv)conv = tf.nn.max_pool(conv, [1, pool_ksize[0], pool_ksize[1], 1], [1, pool_strides[0], pool_strides[1], 1],padding="SAME")return convdef flatten(x_tensor):"""将x_张量压平到(批处理大小,压平图像大小),以方便接下来构建全连接层"""conv_flatten = tf.contrib.layers.flatten(x_tensor)return conv_flattendef fully_conn(x_tensor, num_outputs):""":使用权值和偏置将一个全连接层应用到x_tensor上"""fc_layer = tf.layers.dense(x_tensor, num_outputs, activation=tf.nn.relu)return fc_layerdef output(x_tensor, num_outputs):"""使用权值和偏置应用一个输出层"""output_layer = tf.layers.dense(x_tensor, num_outputs, activation=None)return output_layerdef conv_net(x, keep_prob):"""创建一个卷积神经网络模型: x: 持有图像数据的占位张量。: keep_prob: 持有dropout的占位张量保持概率。: return:表示logits的张量"""conv_layer1 = conv2d_maxpool(x, conv_num_outputs=64, conv_ksize=(5, 5), conv_strides=(2, 2),pool_ksize=(2, 2), pool_strides=(2, 2))conv_layer1 = tf.nn.dropout(conv_layer1, keep_prob)conv_layer2 = conv2d_maxpool(conv_layer1, conv_num_outputs=128, conv_ksize=(3, 3), conv_strides=(2, 2),pool_ksize=(2, 2), pool_strides=(2, 2))conv_layer2 = tf.nn.dropout(conv_layer2, keep_prob)flat_layer = flatten(conv_layer2)fc_layer1 = fully_conn(flat_layer, 256)fc_layer2 = fully_conn(fc_layer1, 128)fc_layer3 = fully_conn(fc_layer2, 64)output_layer = output(fc_layer3, 10)return output_layerdef train_neural_network(session, optimizer, keep_probability
                

更多相关:

  •   在使用tensorflow分类MNIST数据集中,最容易遇到的问题是下载MNIST样本的问题。   一般是通过使用tensorflow内置的函数进行下载和加载,   from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read...