Fashion MNIST 数据及分类 常用的几种模型训练方式

1.mnist fit

import  os
import  tensorflow as tf
from    tensorflow import keras
from    tensorflow.keras import layers, optimizers, datasets
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt


# 可视化一下图片以及对应的标签
# 展示多张图片
def show_imgs(n_rows, n_cols, x_data):
    assert n_rows * n_cols <= len(x_data)  # 保证不会出现数据量不够
    plt.figure(figsize=(n_cols * 2, n_rows * 1.6))
    for row in range(n_rows):
        for col in range(n_cols):
            index = n_cols * row + col  # 得到当前展示图片的下标
            plt.subplot(n_rows, n_cols, index + 1)
            plt.imshow(x_data[index], cmap="binary", interpolation="nearest")
            plt.axis("off")
    plt.show()

def show_single_img(img_arr):
    plt.imshow(img_arr)
    plt.show()

def prepare_mnist_features_and_labels(x, y):
  x = tf.cast(x, tf.float32) / 255.0 #类型转为float32
  y = tf.cast(y, tf.int64)
  return x, y

def mnist_dataset():

  (x, y), (x_val, y_val) = datasets.fashion_mnist.load_data()
  print('x/y shape:', x.shape, y.shape, y_val.shape)
  y = tf.one_hot(y, depth=10)#y为(60000,),one_hot后y变为(60000,10)
  y_val = tf.one_hot(y_val, depth=10)#y_val为(10000,),one_hot后y变为(10000,10)
  print('x/y shape11:', y.shape, y_val.shape)

  ds = tf.data.Dataset.from_tensor_slices((x, y))#ds为60000个(28,28)的矩阵
  ds = ds.map(prepare_mnist_features_and_labels)#修改x,y数据类型
  ds = ds.shuffle(60000).batch(100)#将60000个(28,28)的矩阵随机排列  并100组成一批

  ds_val = tf.data.Dataset.from_tensor_slices((x_val, y_val))
  ds_val = ds_val.map(prepare_mnist_features_and_labels)
  ds_val = ds_val.shuffle(10000).batch(100)

  sample = next(iter(ds))
  print('sample:', sample[0].shape, sample[1].shape)

  # show_imgs(5,5,x) 显示10类图片
  # show_single_img(x[10])#显示单张图片
  return ds,ds_val


class MyModel(keras.Model):

    def __init__(self):
        super(MyModel, self).__init__()

        self.layer1 = layers.Dense(200, activation=tf.nn.relu)#全链接层  如果输入是(m,n)输出是(m,200)
        self.layer2 = layers.Dense(200, activation=tf.nn.relu)
        self.layer3 = layers.Dense(200, activation=tf.nn.relu)
        self.layer4 = layers.Dense(10)#全链接层  如果输入是(m,200)输出是(m,10)

    def call(self, x, training=False):#x为(none,28,28)

        x = tf.reshape(x, [-1, 28*28])#x为(none,784)
        x = self.layer1(x)#x为(none,200)
        x = self.layer2(x)#x为(none,200)
        x = self.layer3(x)#x为(none,200)
        x = self.layer4(x)#x为(none,10)
        return x


def main():

    tf.random.set_seed(22)

    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  # or any {'0', '1', '2'}

    train_dataset, val_dataset = mnist_dataset()

    model = MyModel()
    model.compile(optimizer=optimizers.Adam(1e-3),#优化函数
                  loss=tf.losses.CategoricalCrossentropy(from_logits=True),#s损失函数
                  metrics=['accuracy'])#"accuracy" : y_ 和 y 都是数值,如y_ = [1] y = [1]  #y_为真实值,y为预测值“sparse_accuracy":y_和y都是以独热码 和概率分布表示,如y_ = [0, 1, 0], y = [0.256, 0.695, 0.048]"sparse_categorical_accuracy" :y_是以数值形式给出,y是以 独热码给出,如y_ = [1], y = [0.256 0.695, 0.048]

    callbacks = [keras.callbacks.EarlyStopping(patience=5, min_delta=1e-2)]
    deded = model.fit(train_dataset.repeat(), epochs=200, steps_per_epoch=50, verbose=1,callbacks=callbacks,
              validation_data=val_dataset.repeat(),
              validation_steps=2)

    model.summary()
    plot_learning_curves(deded)

def plot_learning_curves(history):
    # 设置画布大小为8和5
    pd.DataFrame(history.history).plot(figsize=(8, 5))
    # 显示网格
    plt.grid(False)
    # set_ylim为设置y坐标轴的范围
    plt.gca().set_ylim(0, 1)
    plt.show()




if __name__ == '__main__':
    main()

2.mnist matmul

import  os
import  tensorflow as tf
from    tensorflow import keras
from    tensorflow.keras import layers, optimizers, datasets

def prepare_mnist_features_and_labels(x, y):
  x = tf.cast(x, tf.float32) / 255.0
  y = tf.cast(y, tf.int64)
  return x, y



def mnist_dataset():
  (x, y), _ = datasets.fashion_mnist.load_data()#x(60000,28,28) y(60000,)
  #print('x/y shape:', x.shape, y.shape)

  ds = tf.data.Dataset.from_tensor_slices((x, y))#ds为60000个(28,28)的矩阵
  ds = ds.map(prepare_mnist_features_and_labels)#修改x,y数据类型
  ds = ds.take(20000).shuffle(20000).batch(100)#将20000个(28,28)的矩阵随机排列  并100组成一批
  return ds

"""logits:参数labels表示实际标签值
labels:预测值
sparse_softmax_cross_entropy_with_logits:该函数先计算logits的softmax值,再计算softmax与label的cross_entropy
tf.reduce_mean:函数用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值
比如:tf.reduce_mean([1,2,3])=(1 + 2 +3 )/3 = 2, 2就是平均值
"""
def compute_loss(logits, labels):
  return tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=labels))


def compute_accuracy(logits, labels):
  predictions = tf.argmax(logits, axis=1)
  return tf.reduce_mean(tf.cast(tf.equal(predictions, labels), tf.float32))


def train_one_step(model, optimizer, x, y):
  with tf.GradientTape() as tape:
    """获取模型预测值"""
    logits = model(x)
    """将预测值和真实值y对比 计算损失值loss"""
    loss = compute_loss(logits, y)

    """根据loss值以及变量求梯度"""
  grads = tape.gradient(loss, model.trainable_variables)
  """优化器根据梯度,学习率等更新变量x的值"""
  optimizer.apply_gradients(zip(grads, model.trainable_variables))

  accuracy = compute_accuracy(logits, y)

  # loss and accuracy is scalar tensor
  return loss, accuracy


def train(epoch, model, optimizer, train_dataset):
  loss = 0.0
  accuracy = 0.0
  for step, (x, y) in enumerate(train_dataset):#
    loss, accuracy = train_one_step(model, optimizer, x, y)

    if step%500==0:
      print('epoch', epoch, ': loss', loss.numpy(), '; accuracy', accuracy.numpy())
  return loss, accuracy





class MyLayer(layers.Layer):
    def __init__(self, units):
        """
        :param units: [input_dim, h1_dim,...,hn_dim, output_dim]
        """
        super(MyLayer, self).__init__()
        for i in range(1, len(units)):#units传入(784, 200, 200, 10),len为4,因此i的值会为1,2,3
            # w: [input_dim, output_dim]
            self.add_variable(name='kernel%d'%i, shape=[units[i-1], units[i]])
            # b: [output_dim]
            self.add_variable(name='bias%d'%i,shape=[units[i]])



    def call(self, x):
        """
        :param x: [b, input_dim]
        :return:
        """
        num = len(self.trainable_variables)
        x = tf.reshape(x, [-1, 28*28])
        for i in range(0, num, 2):
            x = tf.matmul(x, self.trainable_variables[i]) + self.trainable_variables[i+1]
        return x



def main():
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  # or any {'0', '1', '2'}
    #1.准备数据
    train_dataset = mnist_dataset()
    #2.网络构建类模板
    model = MyLayer([28*28, 200, 200, 10])
    for p in model.trainable_variables:
        print("model.trainable_variables:", p.name, p.shape)#模型参数

    #3.优化函數
    optimizer = optimizers.Adam()

    for epoch in range(20):
        loss, accuracy = train(epoch, model, optimizer, train_dataset)

    print('Final epoch', epoch, ': loss', loss.numpy(), '; accuracy', accuracy.numpy())



if __name__ == '__main__':
    main()

3.mnist_Seqential_gradient

import  os
import  tensorflow as tf
from    tensorflow import keras
from    tensorflow.keras import layers, optimizers, datasets

def prepare_mnist_features_and_labels(x, y):
  x = tf.cast(x, tf.float32) / 255.0
  y = tf.cast(y, tf.int64)
  return x, y

def mnist_dataset():
  (x, y), _ = datasets.fashion_mnist.load_data()
  ds = tf.data.Dataset.from_tensor_slices((x, y))
  ds = ds.map(prepare_mnist_features_and_labels)
  ds = ds.take(20000).shuffle(20000).batch(100)
  return ds

def compute_loss(logits, labels):
  return tf.reduce_mean(
      tf.nn.sparse_softmax_cross_entropy_with_logits(
          logits=logits, labels=labels))


def compute_accuracy(logits, labels):
  predictions = tf.argmax(logits, axis=1)
  return tf.reduce_mean(tf.cast(tf.equal(predictions, labels), tf.float32))


def train_one_step(model, optimizer, x, y):
  with tf.GradientTape() as tape:
    """获取预测值"""
    logits = model(x)
    """预测值logits和真实值y计算 得到损失值loss"""
    loss = compute_loss(logits, y)

  """根据loss值以及变量求梯度"""
  grads = tape.gradient(loss, model.trainable_variables)
  """优化器根据梯度,学习率等更新变量x的值"""
  optimizer.apply_gradients(zip(grads, model.trainable_variables))
  accuracy = compute_accuracy(logits, y)
  return loss, accuracy


def train(epoch, model, optimizer, train_ds):
  loss = 0.0
  accuracy = 0.0
  for step, (x, y) in enumerate(train_ds):
    loss, accuracy = train_one_step(model, optimizer, x, y)
    if step%500==0:
      print('epoch', epoch, ': loss', loss.numpy(), '; accuracy', accuracy.numpy())
  return loss, accuracy

def main():
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1'  # or any {'0', '1', '2'}
    """1.数据准备"""
    train_dataset = mnist_dataset()
    """2.设置训练模型"""
    model = keras.Sequential([
        layers.Reshape(target_shape=(28 * 28,), input_shape=(28, 28)),
        layers.Dense(200, activation='relu'),
        layers.Dense(200, activation='relu'),
        layers.Dense(10)])

    """3.优化函数"""
    optimizer = optimizers.Adam()
    for epoch in range(20):
        loss, accuracy = train(epoch, model, optimizer, train_dataset)
    print('Final epoch', epoch, ': loss', loss.numpy(), '; accuracy', accuracy.numpy())


if __name__ == '__main__':
    main()

sparse_softmax_cross_entropy_with_logits:该函数先计算logits的softmax值,再计算softmax与label的cross_entropy,套详细了解softmax和cross_entropy计算,求查看下面链接:
https://blog.csdn.net/weixin_42713739/article/details/103203743

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页