NJUPT 南京邮电大学 Python编程及人工智能应用实验报告(三)

实验三 神经网络及Python实现实验

  • 实验目的和要求
    1. 掌握全连接神经网络的基本原理。
    2. 掌握卷积神经网络的基本原理。
    3. 学会使用Python,Keras实现全连接神经网络。
    4. 学会使用Python,Keras实现卷积神经网络。
  • 实验原理及内容
  1. 使用全连接神经网络对进行回归分析,预测汽车燃油效率(每加仑燃油公里数);需要对缺失值进行处理。从数据集中抽出后10%作为测试数据集。
    1. 使用Keras搭建神经网络;
    2. 使用matplotlib画出在训练过程中每个epoch对应的训练误差和测试误差;
    3. 对Keras神经网络进行优化训练,并计算测试数据的指标r2mse

数据说明如下:

  1. 每加仑燃油公里数(目标值)
  2. 气缸数
  3. 排量
  4. 马力
  5. 重量
  6. 加速
  7. 模型年份
  8. 原型(类别特征)
  9. 车型(可不使用)

18.0   8   307.0      130.0      3504.      12.0   70  1    "chevrolet chevelle malibu"
15.0   8   350.0      165.0      3693.      11.5   70  1    "buick skylark 320"
18.0   8   318.0      150.0      3436.      11.0   70  1    "plymouth satellite"

        第七章内容的书上的代码得自己敲的,给的链接里并没有后几张的代码,所以让我们先成功地将书上的代码运行后再进行编写。首先先确认好环境的配置,用清华源把你的scikit-learn,tensorflow和pandas装好。可以用pip show来看你是否装好,确保你装的不是空的。

 pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

 pip install tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple

 pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

 pip install scikit-learn -i https://pypi.tuna.tsinghua.edu.cn/simple

 pip install pandas -i Simple Index

下载完成后使用pip show 检验

例:

 好了准备完成,然我们跟着书上敲一遍,完成第一遍尝试吧!

import tensorflow as tf
from keras.datasets import mnist
from keras import models
from keras import layers
import numpy as np
from sklearn.preprocessing import OneHotEncoder
import matplotlib.pyplot as plt


(train_data, train_labels), (test_data, test_labels) = mnist.load_data()
train_data = train_data.reshape((60000, 28 * 28))  # 训练特征转换为一维向量
test_data.astype("float32") / 255  # 归一化,防止数值差值太大
test_data = test_data.reshape((10000, 28 * 28))  # 训练特征转换为一维向量
test_data.astype("float32") / 255  # 归一化,防止数值差值太大

train_labels = train_labels.reshape(60000, 1)
test_labels = test_labels.reshape(10000, 1)  # 标签转换为一维向量

onehot_encoder = OneHotEncoder(sparse=False)  # 设置独热编码格式
train_labels = onehot_encoder.fit_transform(train_labels)  # 得到编码结果
train_labels = tf.squeeze(train_labels)  # 删除编码后维度为1的样本标签
test_labels = onehot_encoder.fit_transform(test_labels)
test_labels = tf.squeeze(test_labels)

neural_net = models.Sequential()  # 组合层级叠加的网络架构
neural_net.add(
    layers.Dense(units=512, activation="relu", input_shape=(28 * 28,))
)  # 设置隐含层的神经元数量和激活函数
neural_net.add(layers.Dense(units=10, activation="softmax"))
# 设置输出层神经元数量和激活函数
neural_net.summary()  # 输出网络初始化的各参数状况

neural_net.compile(  # 配置网络的训练方法
    optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),
    # 设置优化算法为梯度下降,学习率为0.1
    loss="mse",  # 设置损失函数为均方误差
    metrics=["accuracy"],  # 设置变量accuracy用于存储分类准确率
)
history = neural_net.fit(train_data, train_labels, epochs=50, batch_size=512)
# 执行模型的训练
epochs_list = list(range(0, 50))  # 训练次数
loss_list = history.history["loss"]  # 训练的损失值
accuracy_list = history.history["accuracy"]  # 训练的准确率
pre_result = neural_net.predict(test_data)  # 对测试集预测结果
pre_result = np.argmax(pre_result, axis=1)  # 获取图片类别

plt.plot(epochs_list, loss_list, label="loss")
# 以轮次为x轴,损失值为y轴绘制曲线
plt.ylabel("loss")  # Y轴名字
plt.xlabel("epoch")  # X轴名字
plt.legend(["loss"], loc="upper left")  # 设置图例及其位置
plt.show()
plt.plot(epochs_list, accuracy_list, label="accuracy")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(["loss"], loc="upper left")  # 设置图例及其位置
plt.show()
test_loss, test_acc = neural_net.evaluate(test_data, test_labels)
# 测试后的模型
print(test_loss, test_acc)

运行结果如下:

        呃呃,看得出来,我们的neruo sama的成绩似乎并不是很理想,但是没有关系,跑出来就算成功!那我们赶紧熟练地使用ctrl C +Ctrl V完成这道题目吧!

        当然,因为这道题数据的复杂性,所以我们这直接运用pandas进行读取完成,并在简单的分析后发现这其实是依旧是一道线性回归问题,用神经网络去预测第一列的数据,那么第一列作为标签其余数据作为特征去进行训练即可。

        这里读取主要用pandas,因为loadtxt获取后面的字符串还好,主要是这些数据间的分割有的是制表符有的是个数不同的空格,还有缺省值?号的存在,经常报错很难去调整好,所以我们用pandas读取非常便捷。

        首先是获取数据,并将缺省值进行替换。

# 读取文本文件
df = pd.read_csv(
    r"E:\progress\B21030826\python\Automotive_fuel_efficiency.txt",
    sep="\s+",
    header=None,
    na_values=["?"],
)
# 删除所有包含 NaN 值的行
df = df.dropna()
# 只保留最后一列字符串数据,并将其他数据读入
data = df.iloc[:, :-1].values
# 获取最后一列字符串数据
strings = df.iloc[:, -1].values

# 将数据划分为特征和标签
X = data[:, 1:]  # 特征
Y = data[:, 0]  # 标签

        第二步就是堆数据进行处理后划分,将连续特征归一,类型特征编码。

# 对第8列进行独热编码
encod = OneHotEncoder(sparse=False, categories="auto", handle_unknown="ignore")
# OneHotEncoder函数的handle_unknown参数指定了对未知类别的处理方式,
# 默认为'error'(抛出错误),如果原数据中含有未知类别,则会导致编码失败,
# 因此需要将其设置为'ignore'。
prototypes = [[row[7]] for row in data]
prototypes_encoded = encod.fit_transform(prototypes)
# 将编码结果插入到特征矩阵中
X_encoded = np.insert(X, -1, prototypes_encoded.T, axis=1)

# 归一化前7列特征
scaler = MinMaxScaler()
X = scaler.fit_transform(X[:, :7])
# 将数据划分为训练集和10%测试集,随机种子固定好重复实验
train_data, test_data, train_labels, test_labels = train_test_split(
    X, Y, test_size=0.1, random_state=10
)

然后是神经网络的创建并配置对应的学习方法

neural_net = models.Sequential()
# 输入层到第1个隐藏层
neural_net.add(layers.Dense(units=512, activation="relu", input_dim=7))
neural_net.add(
    layers.Dense(units=1, activation="linear")
)  # 输出层,输出1个即可,不使用softmax获取概率,因为是回归问题
print(neural_net.summary())  # 输出网络初始化的各参数状况

# 配置网络的训练方法
neural_net.compile(
    # 设置优化算法为梯度下降,学习率为0.1
    optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),
    loss="mse",  # 设置损失函数为均方误差
    metrics=["accuracy"],  # 设置变量accuracy用于存储分类准确率
)

最后是模型的训练和输出

history = neural_net.fit(
    train_data,
    train_labels,
    epochs=50,
    batch_size=128,
    validation_data=(test_data, test_labels),
)  # 执行模型的训练
epochs_list = list(range(0, 64))  # 训练次数
train_loss_list = history.history["loss"]  # 训练的损失值
test_loss_list = history.history["val_loss"]  # 测试集上的损失值
accuracy_list = history.history["accuracy"]  # 训练的准确率
pre_result = neural_net.predict(test_data)  # 对测试集预测结果
test_loss, test_acc = neural_net.evaluate(test_data, test_labels)  # 测试后的模型
plt.plot(epochs_list, train_loss_list, label="Train Loss")
plt.plot(epochs_list, test_loss_list, label="Test Loss")
plt.ylabel("loss")  # Y轴名字
plt.xlabel("epoch")  # X轴名字
plt.legend(loc="upper left")  # 设置图例及其位置
plt.show()


print("test_loss: ", test_loss, "test_acc: ", test_acc)
r2 = r2_score(test_labels, pre_result)
mse = mean_squared_error(test_labels, pre_result)
print("r2:", r2, "mse:", mse)

然后将最终结果输出,以下为效果图 

0.7几神中神,足够了

但我们简单的优化一下,不如增加训练次数降低神经元数量

neural_net.add(layers.Dense(units=128, activation="relu", input_dim=7))
history = neural_net.fit(
    train_data,
    train_labels,
    epochs=64,
    batch_size=128,
    validation_data=(test_data, test_labels),
)  # 执行模型的训练
epochs_list = list(range(0, 64))  # 训练次数

效果如图:

 给出整体代码:

import numpy as np
import tensorflow as tf
from keras import models
from keras import layers
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score, mean_squared_error
import matplotlib.pyplot as plt
import pandas as pd

# 读取文本文件
df = pd.read_csv(
    r"E:\progress\B21030826\python\Automotive_fuel_efficiency.txt",
    sep="\s+",
    header=None,
    na_values=["?"],
)
# 删除所有包含 NaN 值的行
df = df.dropna()
# 只保留最后一列字符串数据,并将其他数据读入
data = df.iloc[:, :-1].values
# 获取最后一列字符串数据
strings = df.iloc[:, -1].values

# 将数据划分为特征和标签
X = data[:, 1:]  # 特征
Y = data[:, 0]  # 标签

# 对第8列进行独热编码
encod = OneHotEncoder(sparse=False, categories="auto", handle_unknown="ignore")
# OneHotEncoder函数的handle_unknown参数指定了对未知类别的处理方式,
# 默认为'error'(抛出错误),如果原数据中含有未知类别,则会导致编码失败,
# 因此需要将其设置为'ignore'。
prototypes = [[row[7]] for row in data]
prototypes_encoded = encod.fit_transform(prototypes)
# 将编码结果插入到特征矩阵中
X_encoded = np.insert(X, -1, prototypes_encoded.T, axis=1)

# 归一化前7列特征
scaler = MinMaxScaler()
X = scaler.fit_transform(X[:, :7])
# 将数据划分为训练集和10%测试集,随机种子固定好重复实验
train_data, test_data, train_labels, test_labels = train_test_split(
    X, Y, test_size=0.1, random_state=10
)
neural_net = models.Sequential()
# 输入层到第1个隐藏层
neural_net.add(layers.Dense(units=128, activation="relu", input_dim=7))
neural_net.add(
    layers.Dense(units=1, activation="linear")
)  # 输出层,输出1个即可,不使用softmax获取概率,因为是回归问题
print(neural_net.summary())  # 输出网络初始化的各参数状况
# 配置网络的训练方法
neural_net.compile(
    # 设置优化算法为梯度下降,学习率为0.1
    optimizer=tf.keras.optimizers.SGD(learning_rate=0.01),
    loss="mse",  # 设置损失函数为均方误差
    metrics=["accuracy"],  # 设置变量accuracy用于存储分类准确率
)

history = neural_net.fit(
    train_data,
    train_labels,
    epochs=64,
    batch_size=128,
    validation_data=(test_data, test_labels),
)  # 执行模型的训练
epochs_list = list(range(0, 64))  # 训练次数
train_loss_list = history.history["loss"]  # 训练的损失值
test_loss_list = history.history["val_loss"]  # 测试集上的损失值
accuracy_list = history.history["accuracy"]  # 训练的准确率
pre_result = neural_net.predict(test_data)  # 对测试集预测结果
test_loss, test_acc = neural_net.evaluate(test_data, test_labels)  # 测试后的模型
plt.plot(epochs_list, train_loss_list, label="Train Loss")
plt.plot(epochs_list, test_loss_list, label="Test Loss")
plt.ylabel("loss")  # Y轴名字
plt.xlabel("epoch")  # X轴名字
plt.legend(loc="upper left")  # 设置图例及其位置
plt.show()


print("test_loss: ", test_loss, "test_acc: ", test_acc)
r2 = r2_score(test_labels, pre_result)
mse = mean_squared_error(test_labels, pre_result)
print("r2:", r2, "mse:", mse)

但其实还比较好奇那个自定义代码效果,试着敲完编一下。

         我无话可说,书上好像也没给出evaluate的写法,去看keras的源代码model类里evaluate函数打算自己写一个,写着半截,才看到了test可以计算函数,彳亍,这就是没有熟读代码的后果,书上的小错误,让我们直接来看结果。

 很明显这次是真的慢多了,跑了得有两三分钟,不过准确率确实高啊,这才叫优化啊,那么我们先给出书上的自定义代码,若有兴趣可以试着优化一下该题的自定义代码。

书上代码:

import tensorflow as tf
from keras.datasets import mnist
import numpy as np
from tqdm import trange


def Load_data():
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    x_train = x_train.reshape((60000, 28 * 28))  # 训练特征转换为一维向量
    x_test = x_test.reshape((x_test.shape[0], 28 * 28))  # 测试集
    x_train.astype("float32")  # 转换格式
    x_test.astype("float32")  #
    x_train, x_test = x_train / 255, x_test / 255
    y_train = tf.keras.utils.to_categorical(y_train)  # 对标签进行编码
    y_test = tf.keras.utils.to_categorical(y_test)
    return (x_train, y_train), (x_test, y_test)


# 全连接神经网络
class FullConectionLayer:
    def __init__(self):
        self.mem = {}

    def forward(self, X, W):
        self.mem["X"] = X  # 接收输入数据
        self.mem["W"] = W  # 接受网络参数,W网络连接权重矩阵
        H = np.matmul(X, W)  # 网络输出
        return H

    def backward(self, grad_H):
        X = self.mem["X"]  # 获取成员变量
        W = self.mem["W"]
        grad_X = np.matmul(grad_H, W.T)
        grad_W = np.matmul(X.T, grad_H)
        return grad_X, grad_W


# 激活函数和损失函数
class ReLU:
    def __init__(self):
        self.mem = {}

    def forward(self, X):
        self.mem["X"] = X  # 接收输入数据
        return np.where(X > 0, X, np.zeros_like(X))  # 非正数替换成0

    def backward(self, grad_y):
        X = self.mem["X"]
        return (X > 0).astype(np.float32) * grad_y  # 对RELU求导


# 交叉熵损失函数
class CrossEntropy:
    def __init__(self):
        self.mem = {}
        self.epsilon = 1e-12  # 防止求导后分母为0

    def forward(self, p, y):
        self.mem["p"] = p  # 接收输入数据
        log_p = np.log(p + self.epsilon)
        return np.mean(np.sum(-y * log_p, axis=1))  # 计算损失值

    def backward(self, y):  # 计算梯度
        p = self.mem["p"]
        return -y * (1 / (p + self.epsilon))  # 计算损失函数关于p的梯度


class SoftMax:
    def __init__(self):
        self.mem = {}
        self.epsilon = 1e-12  # 防止求导后分母为0

    def forward(self, p):
        p_exp = np.exp(p)
        denominator = np.sum(p_exp, axis=1, keepdims=True)
        s = p_exp / (denominator + self.epsilon)  # softmax的表达式
        self.mem["s"] = s  # 接收输入数据
        self.mem["p_exp"] = p_exp  # 接收输入数据
        return s

    def backward(self, grad_s):  # 计算grad_s的梯度
        s = self.mem["s"]
        siji = np.matmul(np.expand_dims(s, axis=2), np.expand_dims(s, axis=1))
        tmp = np.matmul(np.expand_dims(grad_s, axis=1), siji)  # 矩阵相乘
        tmp = np.squeeze(tmp, axis=1)  # 去掉shape为1的维度
        grad_p = -tmp + grad_s * s
        return grad_p


# 全连接神经网络模型
class FullConectionModel:
    def __init__(self, latent_dims):
        self.W1 = np.random.normal(
            loc=0, scale=1, size=[28 * 28 + 1, latent_dims]
        ) / np.sqrt((28 * 28 + 1) / 2)
        self.W2 = np.random.normal(loc=0, scale=1, size=[latent_dims, 10]) / np.sqrt(
            latent_dims / 2
        )
        self.mul_h1 = FullConectionLayer()  # 隐含层
        self.relu = ReLU()  # 激活函数
        self.mul_h2 = FullConectionLayer()  # 输出层
        self.softmax = SoftMax()  # 激活函数
        self.cross_en = CrossEntropy()  # 损失函数

    def forward(self, X, labels):
        bias = np.ones(shape=[X.shape[0], 1])  # 生成权值均为1的矩阵作为偏置
        X = np.concatenate([X, bias], axis=1)
        self.h1 = self.mul_h1.forward(X, self.W1)  # 隐含层计算
        self.h1_relu = self.relu.forward(self.h1)  # 隐含层激活函数处理
        self.h2 = self.mul_h2.forward(self.h1_relu, self.W2)  # 输出层计算
        self.h2_soft = self.softmax.forward(self.h2)  # 输出层激活函数处理
        self.loss = self.cross_en.forward(self.h2_soft, labels)  # 计算交叉熵损失函数

    def backward(self, labels):
        self.loss_grad = self.cross_en.backward(labels)  # 计算损失函数在输出层的梯度
        self.h2_soft_grad = self.softmax.backward(self.loss_grad)  # 求导
        # 求导
        self.h2_grad, self.W2_grad = self.mul_h2.backward(self.h2_soft_grad)
        self.h1_relu_grad = self.relu.backward(self.h2_grad)  # 求导
        # 计算隐含层的梯度
        self.h1_grad, self.W1_grad = self.mul_h1.backward(self.h1_relu_grad)


# 准确率函数
def computeAccuracy(prob, labels):
    # prob 预测值,labels真实值
    predictions = np.argmax(prob, axis=1)  # 分类结果
    truth = np.argmax(labels, axis=1)  # 获取真实值
    return np.mean(predictions == truth)


# 训练函数
def trainOneStep(model, x_train, y_train, learning_rate=1e-5):
    # 首先定义单步训练函数
    model.forward(x_train, y_train)  # 前向传播
    model.backward(y_train)  # 反向传播
    model.W1 += -learning_rate * model.W1_grad  # 更新参数
    model.W2 += -learning_rate * model.W2_grad  # 更新参数
    loss = model.loss  # 损失函数值
    accuracy = computeAccuracy(model.h2_soft, y_train)  # 计算准确率
    return loss, accuracy


def train(x_train, y_train, x_validation, y_validation):  # 定义训练函数
    epochs = 50  # 训练批次的样本量
    learning_rate = 1e-5  # 学习率
    latent_dims_list = [100, 200, 300]  # 参数列表
    best_accuracy = 0  # 存储最佳的准确率
    best_latent_dims = 0  # 存储最新的参数
    print("Start seaching the best parameter..n")  # 在验证集上寻优
    for latent_dims in latent_dims_list:  # 遍历参数列表
        model = FullConectionModel(latent_dims)  # 在该参数 下运行模型
        bar = trange(20)  # 使用tqdm第三方库,调用tqdm.std.range方法实现以
        # 进度条的显示进度
        for epoch in bar:  # 训练
            loss, accuracy = trainOneStep(model, x_train, y_train, learning_rate)
            # 训练并获损失和准确率
            bar.set_description(
                f"Parameter latent dims= {latent_dims: <3},epoch = {epoch + 1: <3},loss = {loss<10.8},"
                f"accuracy= {accuracy:<8.6}"
            )  # 给进度条加个描述
        bar.close()  # 关闭进度条
        validation_loss, validation_accuracy = test(model, x_validation, y_validation)
        # 运行在验证集
        print(
            f"Parameter latent_dims= {latent_dims: <3}, validation_loss= {validation_loss},validation_accuracy={ validation_accuracy}.\n"
        )  # 显示验证结果

        if validation_accuracy > best_accuracy:  # 判断最佳准确率
            best_accuracy = validation_accuracy  # 获取最高的准确率
            best_latent_dims = latent_dims  # 获取参数列表中各参数对应的准确率

    print(f"The best parameter is {best_latent_dims}.\n")  # 选择最高准确率对应的参数
    print("Start training the best model..")  # 开始训练模型

    best_model = FullConectionModel(best_latent_dims)  # 执行模型
    x = np.concatenate([x_train, x_validation], axis=0)  # 将训练集与验证集合并
    y = np.concatenate([y_train, y_validation], axis=0)  # 将训练集与验证集合并
    bar = trange(epochs)  # 显示进度条
    for epoch in bar:  # 开启训练循环
        loss, accuracy = trainOneStep(best_model, x, y, learning_rate)  # 训练模型
        bar.set_description(
            f"Trining; the best model, epoch={epoch+1: <3}, loss={loss: <10.8},accuracy= {accuracy: <8.6}"
        )  # 给进度条加个描述
    bar.close()  # 关闭进度条
    return best_model  # 返回训|练后的模型


# 测试函数
def test(model, x, y):
    model.forward(x, y)
    loss = model.loss
    accuracy = computeAccuracy(model.h2_soft, y)
    return loss, accuracy


if __name__ == "__main__":
    (train_data, train_labels), (test_data, test_labels) = Load_data()
    valid_data, valid_labels = train_data[:5000], train_labels[:5000]
    train_data, train_labels = train_data[5000:], train_labels[5000:]
    model = train(train_data, train_labels, valid_data, valid_labels)
    loss, accuracy = test(model, test_data, test_labels)
    print(f"Evaluate the best model,test loss={loss:0<10.8},accuracy={accuracy:0<8.6}.")

2、参考最新版第八章“8.6 卷积神经网络及Python实现”内容,完成以下实验。

  1. 参考书上代码,下载MNIST数据,使用Keras/Tensorflow实现基础卷积神经网络对其进行训练和测试预测;
  2. 试着改变卷积神经网络的层数为10层以上,根据自己的想法设置各层,看能否提升分类效果;
     

 惯例,先把书上的图跑一遍,明显跑起来是比全连接神经慢的,花了1min多吧

嗯,82934,没毛病

​​​​​​​

可以,数据还是挺漂亮的

98.8%的正确率,着实恐怖,我们的目标就是超过他。

 先给出书上代码

import numpy as np
import matplotlib.pylab as plt
from keras import Sequential
from keras.datasets import mnist
from keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Flatten


def normorlize(x):
    x = x.astype(np.float32) / 255.0
    return x


(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype("float32")
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype("float32")
x_train = normorlize(x_train)
x_test = normorlize(x_test)

model = Sequential()
model.add(Conv2D(filters=8, kernel_size=(5, 5), padding='same', input_shape=(28, 28, 1), activation='relu'))  # 第一层卷积层
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))  # 第一个池化层

model.add(Conv2D(filters=16, kernel_size=(5, 5), padding='same', activation='relu'))  # 第二层卷积层
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))   # 第二个池化层

model.add(Flatten())  # 将特征图展开为一维
model.add(Dense(256, activation='relu'))  # 全连接层的隐含层
model.add(Dropout(0.5))  # Dropout防止过拟合
model.add(Dense(10, activation='softmax'))  # 全连接层的输出层

print(model.summary())

model.compile(
    loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"]
)

history = model.fit(
    x=x_train, y=y_train, validation_split=0.2, epochs=4, batch_size=250, verbose=1
)
# 执行模型的训练

loss_list = history.history["loss"]  # 训练的损失值
val_loss = history.history["val_loss"]  # 训练的损失值
acc_list = history.history["accuracy"]  # 训练的准确率
val_acc = history.history["val_accuracy"]

plt.plot(acc_list, label="Accuracy")
plt.plot(val_acc, label="Validation Accuracy")  # 绘制这两个数据的变化图
# 以轮次为x轴,损失值为y轴绘制曲线
plt.ylabel("Accuracy")  # Y轴名字
plt.xlabel("Epoch")  # X轴名字
plt.ylim([0.75, 1])  # 坐标轴范围
plt.legend(loc="lower right")  # 设置图例及其位置
plt.show()
plt.plot(loss_list, label="Loss")
plt.plot(val_loss, label="Validation Loss")  # 绘制这两个数据的变化图
# 以轮次为x轴,损失值为y轴绘制曲线
plt.ylabel("Loss")  # Y轴名字
plt.xlabel("Epoch")  # X轴名字
plt.ylim([0, 0.6])  # 坐标轴范围
plt.legend(loc="upper right")  # 设置图例及其位置
plt.show()
test_loss, test_acc = model.evaluate(x_test, y_test)
# 测试后的模型
print("loss: ", test_loss, "acc:  ", test_acc)

随便改改,12层网络,轻松搞定。

import numpy as np
import matplotlib.pylab as plt
from keras import Sequential
from keras.datasets import mnist
from keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Flatten


def normorlize(x):
    x = x.astype(np.float32) / 255.0
    return x


(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1).astype("float32")
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1).astype("float32")
x_train = normorlize(x_train)
x_test = normorlize(x_test)

model = Sequential()
model.add(Conv2D(filters=8, kernel_size=(5, 5), padding='same', input_shape=(28, 28, 1), activation='relu'))  # 第一层卷积层
model.add(Conv2D(filters=8, kernel_size=(9, 9), padding='same', activation='relu'))  # 第二层卷积层
model.add(MaxPooling2D(pool_size=(1, 1), padding='same'))  # 第一个池化层

model.add(Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu'))  # 第三层卷积层
model.add(Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu'))  # 第四层卷积层
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))   # 第二个池化层

model.add(Conv2D(filters=32, kernel_size=(5, 5), padding='same', activation='relu'))  # 第五层卷积层
model.add(Conv2D(filters=32, kernel_size=(5, 5), padding='same', activation='relu'))  # 第六层卷积层
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))  # 第三个池化层

model.add(Conv2D(filters=16, kernel_size=(3, 3), padding='same', activation='relu'))  # 第七层卷积层
model.add(MaxPooling2D(pool_size=(1, 1), padding='same'))   # 第四个池化层

model.add(Flatten())  # 将特征图展开为一维
model.add(Dense(256, activation='relu'))  # 全连接层的隐含层
model.add(Dropout(0.5))  # Dropout防止过拟合
model.add(Dense(10, activation='softmax'))  # 全连接层的输出层

print(model.summary())

model.compile(
    loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"]
)

history = model.fit(
    x=x_train, y=y_train, validation_split=0.2, epochs=4, batch_size=250, verbose=1
)
# 执行模型的训练

loss_list = history.history["loss"]  # 训练的损失值
val_loss = history.history["val_loss"]  # 训练的损失值
acc_list = history.history["accuracy"]  # 训练的准确率
val_acc = history.history["val_accuracy"]

plt.plot(acc_list, label="Accuracy")
plt.plot(val_acc, label="Validation Accuracy")  # 绘制这两个数据的变化图
# 以轮次为x轴,损失值为y轴绘制曲线
plt.ylabel("Accuracy")  # Y轴名字
plt.xlabel("Epoch")  # X轴名字
plt.ylim([0.75, 1])  # 坐标轴范围
plt.legend(loc="lower right")  # 设置图例及其位置
plt.show()
plt.plot(loss_list, label="Loss")
plt.plot(val_loss, label="Validation Loss")  # 绘制这两个数据的变化图
# 以轮次为x轴,损失值为y轴绘制曲线
plt.ylabel("Loss")  # Y轴名字
plt.xlabel("Epoch")  # X轴名字
plt.ylim([0, 0.6])  # 坐标轴范围
plt.legend(loc="upper right")  # 设置图例及其位置
plt.show()
test_loss, test_acc = model.evaluate(x_test, y_test)
# 测试后的模型
print("loss: ", test_loss, "acc:  ", test_acc)

 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值