【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(2)Keras


文章目录

  • 前言
  • 一、Keras
  • [二、使用Kears 估计回归问题的神经网络](#二、使用Kears 估计回归问题的神经网络)
    • [1. 载入、处理数据](#1. 载入、处理数据)
    • [2. 数据预处理:归一化](#2. 数据预处理:归一化)
    • [3. 设定一系列随机数种子](#3. 设定一系列随机数种子)
    • [4. 定义了一个简单的深度神经网络](#4. 定义了一个简单的深度神经网络)
    • [5. 训练模型](#5. 训练模型)
    • [6. 查看训练结果](#6. 查看训练结果)
    • [7. 使用最优轮数(index+1)重新估计 此神经网络模型](#7. 使用最优轮数(index+1)重新估计 此神经网络模型)
    • [8. 预测 & 混淆函数](#8. 预测 & 混淆函数)
  • [三、使用Kears 估计 二分类问题的神经网络](#三、使用Kears 估计 二分类问题的神经网络)
    • [1. 载入、处理数据](#1. 载入、处理数据)
    • [2. 估计 二分类问题的神经网络](#2. 估计 二分类问题的神经网络)
    • [3. 使用最优轮数(index+1)重新估计 此神经网络模型](#3. 使用最优轮数(index+1)重新估计 此神经网络模型)
    • [4. 预测 & 混淆函数](#4. 预测 & 混淆函数)
    • [5. 加入 L~2~ 惩罚项进行权重衰减](#5. 加入 L2 惩罚项进行权重衰减)
    • 6.使用"丢包法"(Dropout)进行正则化
  • [四、使用Kears 估计 多分类问题的神经网络](#四、使用Kears 估计 多分类问题的神经网络)
    • [1. 载入、处理数据](#1. 载入、处理数据)
    • [2. 估计 多分类问题的神经网络](#2. 估计 多分类问题的神经网络)
    • [3. 预测 & 混淆函数](#3. 预测 & 混淆函数)
  • [五、使用Kears 估计 卷积神经网络CNN](#五、使用Kears 估计 卷积神经网络CNN)
    • [1. 载入、处理数据](#1. 载入、处理数据)
    • [2. 估计 CNN](#2. 估计 CNN)
    • [3. 预测 & 混淆函数](#3. 预测 & 混淆函数)
  • 附:系列文章目录

前言

本学习笔记 仅为以防自己忘记了,顺便分享给一起学习的网友们参考。如有不同意见/建议,可以友好讨论。

本学习笔记 所有的代码和数据都可以从 陈强老师的个人主页 上下载

参考书目:陈强.机器学习及Python应用. 北京:高等教育出版社, 2021.

数学原理等 详见陈强老师的 PPT


参考了:网友伪_装CNN对 MNIST 数据集中的图像进行分类


一、Keras

sklearn只能估计前馈神经网络,而无法估计卷积神经网络、循环神经网络等其他神经网络模型。

Keras 可调用一些低层的深度学习框架, 并以这些深度学习框架作为其"后端引擎" 。

Python Keras 的主要特点

  • 用户友好:Keras 提供了简单而直观的 API,适用于深度学习新手和专家。
  • 模块化:您可以轻松地构建、训练和评估各种神经网络模型。
  • 可扩展性:Keras 支持卷积神经网络(CNN)、循环神经网络(RNN)、自动编码器、生成对抗网络(GAN)等各种类型的神经网络。
  • 多后端支持:Keras 可以在不同的深度学习后端上运行,如 TensorFlow、Theano 和 CNTK。
  • 社区支持:Keras 拥有庞大的用户社区和丰富的文档,可以轻松获得支持和学习资源。

安装

复制代码
pip install keras

二、使用Kears 估计回归问题的神经网络

使用Keras自带数据 波士顿房价boston_housing

1. 载入、处理数据

python 复制代码
'''回归问题的神经网络模型''' 
import numpy as np
import random as rn
import pandas as pd
import tensorflow as tf
import keras
#载入Keras自带数据 波士顿房价
from keras.datasets import boston_housing 

# 将数据分割为训练集(80%)和测试集(20%)
from sklearn.model_selection import train_test_split

(X_train, Y_train), (X_test, Y_test) = boston_housing.load_data(
    test_split=0.2, seed=113)

#查看 X_train的形状
X_train.shape,

结果输出: ((404, 13), (102, 13))

python 复制代码
Y_train[:5], Y_test[:5]

结果输出: (array([15.2, 42.3, 50. , 21.1, 17.7]), array([ 7.2, 18.8, 19. , 27. , 22.2]))

2. 数据预处理:归一化

python 复制代码
#将 特征变量归一化
from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
scaler.fit(X_train)
X_train_s = scaler.transform(X_train)
X_test_s = scaler.transform(X_test)

结果输出: 0.935

3. 设定一系列随机数种子

python 复制代码
#设定一系列随机数种子
import os
import random as rn

def set_my_seed():
    os.environ['PYTHONHASHSEED']='0'
    np.random.seed(1)           # 设置 NumPy 随机种子
    rn.seed(12345)
    tf.random.set_seed(123)   # 设置 TensorFlow 随机种子

set_my_seed()

4. 定义了一个简单的深度神经网络

python 复制代码
#定义一个用于构建网络的函数,便于后续调用
from keras.models import Sequential #Sequential是一种线性堆叠模型,适用于大多数简单的神经网络架构。
from keras.layers import Dense #Dense层是全连接层(即每个神经元都与前一层的所有神经元连接),常用于构建深度学习模型。

def build_model():
    model = Sequential()
    model.add(
        Dense(units=256, #包含256个神经元
              activation='relu', #激活函数为ReLU(修正线性单元)
              input_shape=(X_train_s.shape[1],))) #指定输入数据的形状。X_train_s.shape[1]表示输入特征的数量。
    model.add(Dense(units=256, activation='relu'))
    model.add(Dense(units=1)) #添加最终的全连接层,这一层只有1个神经元,通常用于回归问题的输出层,表示预测一个连续值。
    model.compile( #编译模型,准备进行训练。
    	optimizer='rmsprop',  #RMSProp(Root Mean Square Propagation)是一种自适应学习率优化算法
        loss='mse', #设置损失函数为均方误差(MSE)
        metrics=['mse']) # 设置评估指标为均方误差(MSE)
    return model #返回构建好的模型实例,以便后续调用和使用。

# 创建模型
model = build_model()

#模型概要信息
model.summary()

5. 训练模型

python 复制代码
# 训练模型
hist = model.fit(
    X_train_s, Y_train, 
    validation_split=0.25, #25%的训练集作为验证集
    epochs=300, #训练300轮
    batch_size=16, #小批量梯度下降的每批次容量为16个观测值
    shuffle = False) #新一轮迭代时不随机打乱

#查看hist的类型
type(hist)

结果输出: keras.src.callbacks.history.History
hist 变量的类型是 History 对象,属于 Keras 库中的 callbacks 模块。 History 对象中包含了在训练过程中记录的所有指标,包括训练和验证损失(loss)和其他监控指标(如准确率)等。

6. 查看训练结果

python 复制代码
Dict = hist.history
Dict.keys()

结果输出: dict_keys(['loss', 'mse', 'val_loss', 'val_mse'])

python 复制代码
val_mse = Dict['val_mse'] #取出验证集的均分误差
min(val_mse)

结果输出: 10.776559829711914

python 复制代码
#最小val_mse的位置
index = np.argmin(val_mse)
index

结果输出: 293

python 复制代码
#画图展示训练集与测试集的均分误差
import matplotlib.pyplot as plt
import seaborn as sns

plt.plot(Dict['mse'], 'k', label='Train')  
plt.plot(Dict['val_mse'], 'b', label='Validation') 
plt.axvline(index + 1, linestyle='--', color='k')

plt.xlabel('Epochs')
plt.ylabel('MSE')
plt.title('MSE on Test & Validation')
plt.legend()
python 复制代码
#训练集MSE的最小值
train_mse = Dict['mse']
min(train_mse)

结果输出: 2.683964490890503

python 复制代码
#最小训练集MSE的位置
index_train = np.argmin(train_mse)
index_train

结果输出: 293

7. 使用最优轮数(index+1)重新估计 此神经网络模型

python 复制代码
set_my_seed()
model = build_model()
model.fit(
    X_train_s, Y_train, 
    epochs= index + 1, #index + 1 表示训练的次数取决于变量 index 的值。这个设计允许动态调整训练的次数,可能用于模型调优或逐步训练。
    batch_size=16, #每批次包含16个观测值
    verbose = 0) #不显示估计过程

#得出测试集的损失函数与均方误差
model.evaluate(X_test_s, Y_test)

结果输出: [11.855478286743164, 11.855478286743164]
evaluate 方法会返回一个列表,其中包含模型在测试集上的损失值以及其他指标的值(如果在模型编译时指定了其他评估指标)。 [loss, metrics]。

8. 预测 & 混淆函数

python 复制代码
pred = model.predict(X_test_s)
pred.shape

结果输出: (102, 1)

python 复制代码
#将102×1的二维矩阵压缩为向量
pred = np.squeeze(pred)
pred.shape

结果输出: (102,)

python 复制代码
#相关系数矩阵---Numpy的corrcoef()
np.corrcoef(Y_test,pred) ** 2

结果输出:

array([[1. , 0.86602909],

0.86602909, 1. \]\]) `拟合优度=0.86602909` ## 三、使用Kears 估计 二分类问题的神经网络 对于二分类问题,使用Keras 估计神经网络模型的流程与上述回归问题 类似。 主要差别在于损失函数应设为"binary_crossentropy " (二值交叉熵)。 使用过滤垃圾邮件的spam数据( 参见[【学习笔记】 陈强-机器学习-Python-Ch8 朴素贝叶斯](https://blog.csdn.net/2201_76026029/article/details/141142107) ) ### 1. 载入、处理数据 ```python '''二分类问题--损失函数为 binary_crossentropy''' import numpy as np import pandas as pd import tensorflow as tf import keras #读取CSV文件的路径 csv_path = r'D:\桌面文件\Python\【陈强-机器学习】MLPython-PPT-PDF\MLPython_Data\spam.csv' spam = pd.read_csv(csv_path) #定义X与y X = spam.iloc[:, :-1] y = spam.iloc[:, -1] y = pd.get_dummies(y).iloc[:,1] #全样本随机分20%测试集和80%训练集 from sklearn.model_selection import train_test_split X_trainval, X_test, y_trainval, y_test = train_test_split( X, y, stratify=y, test_size=1000, random_state=0) X_train, X_val, y_train, y_val = train_test_split( X_trainval, y_trainval, stratify=y_trainval, test_size=1000, random_state=0) #特征变量 标准化 from sklearn.preprocessing import StandardScaler, MinMaxScaler #生成一个实例scaler scaler = MinMaxScaler() #进行估计 scaler.fit(X_train) #使用transform()分别将 训练集、测试集的特征变量进行标准化 X_train_s = scaler.transform(X_train) X_val_s = scaler.transform(X_val) X_trainval_s = scaler.transform(X_trainval) X_test_s = scaler.transform(X_test) ``` ### 2. 估计 二分类问题的神经网络 ```python #设定一系列随机数种子 import os import random as rn import random as rn import tensorflow as tf def set_my_seed(): os.environ['PYTHONHASHSEED']='0' np.random.seed(1) # 设置 NumPy 随机种子 rn.seed(12345) tf.random.set_seed(12345) # 设置 TensorFlow 随机种子 set_my_seed() #定义一个用于构建网络的函数,便于后续调用 from keras.models import Sequential from keras.layers import Dense set_my_seed() def build_model(): model = Sequential() model.add( Dense(units=256, #包含256个神经元 activation='relu', input_shape=(X_train_s.shape[1],))) model.add(Dense(units=256, activation='relu')) model.add(Dense(units=1,activation='sigmoid')) model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy']) return model # 创建模型 model = build_model() #模型概要信息 model.summary() ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/9170064efa3b46da86c38a772154c775.png) ```python # 训练模型 hist = model.fit( X_train_s, y_train, validation_data = (X_val_s, y_val), #指定验证集数据 epochs = 50, #迭代50抡 batch_size = 64, #小批量梯度下降的每批次容量为64个观测值 shuffle = False) #查看模型训练历史的各个指标 hist.history.keys() ``` **结果输出:** dict_keys(\['accuracy', 'loss', 'val_accuracy', 'val_loss'\]) ```python #最小 验证集 损失 val_loss = hist.history['val_loss'] index_min = np.argmin(val_loss) index_min ``` **结果输出:** 29 ```python #画图展示 import matplotlib.pyplot as plt import seaborn as sns plt.plot(hist.history['loss'], 'k', label='Training Loss') plt.plot(val_loss, 'b', label='Validation Loss') plt.axvline(index_min + 1, linestyle='--', color='k', linewidth=1) plt.xlabel('Epochs') plt.ylabel('Loss') plt.title('Training & Validation Loss') plt.legend() ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/7d29d86432724a37aaf18b15eb9047c2.png) ```python #最大 验证集 准确率 val_accuracy = hist.history['val_accuracy'] print(np.max(val_accuracy)) index_max = np.argmax(val_accuracy) print(index_max) ``` **结果输出:** 0.9430000185966492 39 ```python plt.plot(hist.history['accuracy'], 'k', label='Training Accuracy') plt.plot(val_accuracy, 'b', label='Validation Accuracy') plt.axvline(index_max, linestyle='--', color='k', linewidth=1) plt.xlabel('Epochs') plt.ylabel('Accuracy') plt.title('Training & Validation Accuracy') plt.legend() ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e04ec12c7ce84eb7bbcec8879b392e09.png) ### 3. 使用最优轮数(index+1)重新估计 此神经网络模型 ```python set_my_seed() model = build_model() hist = model.fit( X_trainval_s, y_trainval, epochs = index_max + 1, batch_size = 64, verbose = 0, shuffle = False) #计算 测试集的损失函数与均方误差 model.evaluate(X_test_s, y_test) ``` **结果输出:** \[0.15308548510074615, 0.953000009059906

4. 预测 & 混淆函数

python 复制代码
#在测试集中预测
prob = model.predict(X_test_s)
prob[:5]

结果输出: array([[9.985374e-01],

9.828230e-01\], \[9.423103e-01\], \[7.494897e-09\], \[2.156171e-03\]\], dtype=float32) 陈强老师在书里用到的`predict_classes()`已经在Keras2.6 之后就被弃用了。我就简单地将概率大于0.5的设置为1。 ```python #0-1划分 pred_classes = (prob > 0.5).astype(int) #混淆矩阵 from sklearn.metrics import ConfusionMatrixDisplay ConfusionMatrixDisplay.from_predictions( y_test, pred_classes) ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/43081493b4664dd58683aadb0619a52e.png) ### 5. 加入 L~2~ 惩罚项进行权重衰减 ```python #加入L2惩罚项进行权重衰减 from keras import regularizers set_my_seed() def build_model(): model = Sequential() model.add( Dense(units=256, activation='relu', kernel_regularizer=regularizers.l2(0.0001), #使用L2正则化 input_shape=(X_train_s.shape[1],) ) ) model.add(Dense(units=256, activation='relu', kernel_regularizer=regularizers.l2(0.0001) #使用L2正则化 ) ) model.add( Dense(units=1, activation='sigmoid') ) model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy']) return model model_L2 = build_model() model_L2.summary() ``` ![**结果输出:**](https://i-blog.csdnimg.cn/direct/c29a3febc4654915a6c9332471131db1.png) ```python # 训练模型 hist = model_L2.fit( X_train_s, y_train, validation_data = (X_val_s, y_val), epochs = 50, batch_size = 64, shuffle = False) #最大 验证集 准确率 val_accuracy = hist.history['val_accuracy'] print(np.max(val_accuracy)) index_max = np.argmax(val_accuracy) index_max ``` **结果输出:** 0.9399999976158142 25 ```python #计算最优轮数(index+1) 模型的测试集的损失函数与预测准确率 set_my_seed() model = build_model() hist = model.fit( X_trainval_s, y_trainval, epochs = index_max + 1, batch_size = 64, verbose = 0, shuffle = False) model.evaluate(X_test_s, y_test) ``` **结果输出:** \[0.18239134550094604, 0.9480000138282776

准确率低于没有进行权重衰减前

6.使用"丢包法"(Dropout)进行正则化

python 复制代码
#用dropout进行正则化
from keras.layers import Dropout 

set_my_seed()

def build_model():
    model = Sequential()
    model.add(Dense(units=256,  
              activation='relu',
              input_shape=(X_train_s.shape[1],)
             ))
    model.add(Dropout(0.2)) #随机丢掉在其前面隐藏层的20%神经元
    model.add(Dense(units=256, activation='relu'))
    model.add(Dropout(0.2)) #随机丢掉在其前面隐藏层的20%神经元
    model.add(Dense(units=1, activation='sigmoid'))
    model.compile(optimizer='rmsprop', 
                  loss='binary_crossentropy',
                  metrics=['accuracy'])
    return model

# 创建模型
model = build_model()

# 训练模型
hist = model.fit(
    X_train_s, y_train, 
    validation_data=(X_val_s, y_val),
    epochs=50, 
    batch_size=64,
    shuffle=False
)

#最大 验证集 准确率
val_accuracy = hist.history['val_accuracy']
print(np.max(val_accuracy))
index_max = np.argmax(val_accuracy)
index_max

结果输出: 0.9490000009536743

49

python 复制代码
#计算最优轮数(index+1) 模型的测试集的损失函数与预测准确率
set_my_seed()
model = build_model()
hist = model.fit(
        X_trainval_s,
        y_trainval, 
        epochs = index_max + 1, 
        batch_size = 64,
        verbose = 0,
        shuffle = False) 
model.evaluate(X_test_s, y_test)

结果输出:[0.15388594567775726, 0.9580000042915344]

四、使用Kears 估计 多分类问题的神经网络

对于多分类问题,使用Keras 估计神经网络模型的流程与上述二分类问 题类似。 主要差别在于损失函数应设为"categorical_crossentropy "。

使用Keras自带的 路透社新闻数据reuters 进行演示。

1. 载入、处理数据

python 复制代码
'''多分类问题--损失函数为 categorical_crossentropy'''
import numpy as np
import pandas as pd

#使用Keras自带的 路透社新闻
from keras.datasets import reuters

#分测试集和训练集
(X_trainval, y_trainval_original), (X_test, y_test_original) = reuters.load_data(
    num_words=1000) #仅导入最频繁出现的1000种词汇

#查看 X_trainval & X_test  形状
X_trainval.shape, X_test.shape

结果输出: ((8982,), (2246,))

python 复制代码
#查看 y_trainval_original 的分类归属
y_trainval_original[0], y_test_original[0]

结果输出: (3, 3)

python 复制代码
#将y_trainval_original转设为pd.DataFrame,通过直方图考察其取值分布
y_trainval_original=pd.DataFrame(
    y_trainval_original,columns=['topic'])
y_trainval_original.hist(bins=46) #分为46组(每个取值一组)
python 复制代码
'''需要将X_trainval & X_test 这两个一位数组向量化'''
#定一个函数用于转换
def vectorize_lists(lists, dimension =1000): #定义一个名为 vectorize_lists 的函数,该函数接收两个参数:lists(输入的列表),   dimension=1000(向量的维度,默认为 1000。这个参数指定了每个列表在向量化后应有的长度。)
    results = np.zeros(
        (len(lists),dimension)
        ) #创建一个全为零的 NumPy 数组 results,其形状为 (len(lists), dimension)。
    for i, list in enumerate(lists): #使用 enumerate 函数遍历 lists,同时获取当前列表的索引 i 和内容 list
        results[i, list] = 1 
        return results

#将函数 作用于 X_trainval & X_test
X_trainval=vectorize_lists(X_trainval)
X_test=vectorize_lists(X_test)

#查看 X_trainval & X_test  形状
X_trainval.shape, X_test.shape

结果输出: ((8982, 1000), (2246, 1000))

python 复制代码
#使用Keras的 to_categorical() 函数,将响应变量 y_trainval_original &  y_test_original 转变为虚拟变量组成的矩阵
from tensorflow.keras.utils import to_categorical

y_trainval = to_categorical(y_trainval_original)
y_test = to_categorical(y_test_original)

#查看 y_trainval_original &  y_test_original 形状
y_trainval.shape, y_test.shape

结果输出: ((8982, 46), (2246, 46))

python 复制代码
#分为: 训练集 与 验证集
from sklearn.model_selection import train_test_split

X_train, X_val, y_train, y_val = train_test_split(
    X_trainval, y_trainval, stratify = y_trainval_original, 
     test_size=1000, random_state=321)

2. 估计 多分类问题的神经网络

之前的部分虽然有些和陈强老师书里的结果有些出入,但是还是能接受的。从这个部分开始,结果开始走向无法挽救的失败。之前我可能还会质疑书,但是这个部分开始,我非常确信是我的代码哪里没对,但是我找不到不对的地方!!!

python 复制代码
#设定一系列随机数种子
import os
import random as rn
import random as rn
import tensorflow as tf

def set_my_seed():
    os.environ['PYTHONHASHSEED']='0'
    np.random.seed(1)           
    rn.seed(12345)
    tf.random.set_seed(123)   

set_my_seed()

#定义一个用于构建网络的函数,便于后续调用
from keras.models import Sequential 
from keras.layers import Dense
from keras.layers import Dropout 

def build_model():
    model = Sequential()
    model.add(Dense(units=512, 
              activation='relu',
              input_shape=(X_train.shape[1],)
             ))
    model.add(Dropout(0.25))
    model.add(Dense(units=512, activation='relu'))
    model.add(Dropout(0.25))
    model.add(Dense(units=46, activation='softmax')) #使用softmax作为输出层激活函数
    model.compile(optimizer='rmsprop', 
                  loss='categorical_crossentropy', #多分类交叉熵损失函数
                  metrics=['accuracy'])
    return model

# 创建模型
model = build_model()

#模型概要信息
model.summary()
python 复制代码
# 模型估计
hist = model.fit(
    X_train, y_train, 
    validation_data=(X_val, y_val),
    epochs=30, 
    batch_size=64,
    shuffle=False)

#最小验证集 损失
val_loss = hist.history['val_loss']
index_min = np.argmin(val_loss)
index_min

结果输出: 27

python 复制代码
import matplotlib.pyplot as plt
import seaborn as sns

plt.plot(hist.history['loss'], 'k', label='Training Loss')  
plt.plot(val_loss, 'b', label='Validation Loss')  
plt.axvline(index_min + 1, linestyle='--', color='k', linewidth=1)

plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.title('Training & Validation Loss')
plt.legend()
python 复制代码
#最大 验证集 准确率
val_accuracy = hist.history['val_accuracy']
print(np.max(val_accuracy))
index_max = np.argmax(val_accuracy)
print(index_max)

**结果输出:**0.35199999809265137

0

python 复制代码
plt.plot(hist.history['accuracy'], 'k', label='Training Accuracy')  
plt.plot(val_accuracy, 'b', label='Validation Accuracy')  
plt.axvline(index_max, linestyle='--', color='k', linewidth=1)

plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.title('Training & Validation Accuracy')
plt.legend()

3. 预测 & 混淆函数

python 复制代码
#在测试集中预测
prob = model.predict(X_test_s)
prob[0].shape

结果输出: (46,)

python 复制代码
# 获取每个样本的类别索引
pred = np.argmax(prob, axis=1)
#混淆矩阵
from sklearn.metrics import confusion_matrix
table = confusion_matrix(y_test_original, pred)
table

array([[0, 0, 0, ..., 0, 0, 0],

0, 0, 0, ..., 0, 0, 0\], \[0, 0, 0, ..., 0, 0, 0\], ..., \[0, 0, 0, ..., 0, 0, 0\], \[0, 0, 0, ..., 0, 0, 0\], \[0, 0, 0, ..., 0, 0, 0\]\], dtype=int64) ```python #热力图 sns.heatmap(table, cmap = 'Blues') plt.xlabel('predicted') plt.ylabel('ture') plt.title('confusion_matrix') ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c994a352d4e5409f874c10e9a0efb801.png) ## 五、使用Kears 估计 卷积神经网络CNN 这个部分开始和多分类一样让我头秃,结果一眼就知道有问题......但是我找不到不对的地方!!! 使用著名的手写数字数据集mnist(Keras自带) ### 1. 载入、处理数据 ```python import tensorflow as tf import keras # 加载Keras中的MNIST数据集 from keras.datasets import mnist #分测试集和训练集 (X_train, y_train), (X_test, y_test) = mnist.load_data() #查看 X_trainval & X_test 形状 X_train.shape, X_test.shape ``` **结果输出:**(60000, 28, 28), (10000, 28, 28)) ```python import matplotlib.pyplot as plt plt.imshow(X_train[4], cmap=plt.cm.gray_r) ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/070d58fdd1ce495fa60624121316b054.png) ```python #验证y_train 第四个元素 y_train[4] ``` **结果输出:** 9 ```python #测试集分为 训练集和验证集 与测试集 from sklearn.model_selection import train_test_split X_trainval, X_test, y_trainval, y_test = train_test_split( X_test, y_test, stratify=y_test, test_size=0.4, random_state=0) #等额训练集和验证集 X_train, X_val, y_train, y_val = train_test_split( X_trainval, y_trainval, stratify=y_trainval, test_size=0.5, random_state=359) #考察特征变量的最小值 & 最大值 import numpy as np np.min(X_train), np.max(X_train) ``` **结果输出:** (0, 255) ```python #查看X_train的类型 X_train.dtype ``` **结果输出:** dtype('uint8') ```python #将数据转为32位浮点 X_trainval = X_trainval.astype('float32') X_train = X_train.astype('float32') X_val = X_val.astype('float32') X_test = X_test.astype('float32') #归一化 X_trainval /= 255 X_train /= 255 X_val /= 255 X_test /= 255 X_trainval.shape, X_train.shape, X_val.shape, X_test.shape ``` **结果输出:** ((6000, 28, 28), (3000, 28, 28), (3000, 28, 28), (4000, 28, 28)) ```python #为 数组增加一个维度 X_trainval = X_trainval.reshape((6000, 28, 28, 1)) X_train = X_train.reshape((3000, 28, 28, 1)) X_val = X_val.reshape((3000, 28, 28, 1)) X_test = X_test.reshape((4000, 28, 28, 1)) X_trainval.shape, X_train.shape, X_val.shape, X_test.shape ``` **结果输出:** ((6000, 28, 28, 1), (3000, 28, 28, 1), (3000, 28, 28, 1), (4000, 28, 28, 1)) ```python #处理Y: 虚拟矩阵 to_categorical() from keras.utils import to_categorical y_trainval = to_categorical(y_trainval) y_train = to_categorical(y_train) y_val = to_categorical(y_val) y_test_original = y_test y_test = to_categorical(y_test) y_train.shape, y_val.shape, y_test.shape ``` **结果输出:**((3000, 10), (3000, 10), (4000, 10)) ### 2. 估计 CNN ```python #设定一系列随机数种子 import os import random as rn import random as rn import tensorflow as tf def set_my_seed(): os.environ['PYTHONHASHSEED']='0' np.random.seed(1) rn.seed(12345) tf.random.set_seed(123) set_my_seed() #定义一个用于构建网络的函数,便于后续调用 import keras from keras.models import Sequential from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout from keras.optimizers import Adadelta def build_model(): model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), #向模型添加第一个卷积层:32(输出通道数,表示该层将生成 32 个特征图);kernel_size=(3, 3): 卷积核的大小为 3x3。 activation='relu', input_shape=(28, 28, 1))) # 输入形状为 28x28 像素的单通道图像(如灰度图)。 model.add(Conv2D(64, (3, 3), activation='relu')) #添加第二个卷积层: 64(输出通道数,表示该层将生成 64 个特征图。)(3, 3): 卷积核的大小为 3x3。 model.add(MaxPooling2D(pool_size=(2, 2))) #添加最大池化层:pool_size=(2, 2): 池化窗口的大小为 2x2,用于下采样,减少特征图的维度。 model.add(Dropout(0.25)) model.add(Flatten()) #添加 Flatten 层: 将多维输入展平为一维数组,为全连接层做准备。 model.add(Dense(128, activation='relu')) #添加第一个全连接层:128(输出节点数为 128) model.add(Dropout(0.25)) model.add(Dense(10, activation='softmax')) #添加最后的全连接层:10(输出节点数为 10,通常对应于 10 个分类(如手写数字 0-9)。 model.compile( optimizer=keras.optimizers.Adadelta(), # 使用 Adadelta 作为优化器 loss='categorical_crossentropy', metrics=['accuracy']) return model # 创建模型 model = build_model() #模型概要信息 model.summary() ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/80473db2ad594f1a8cde00ca1d42f519.png) ```python # 估计模型 hist = model.fit(X_train, y_train, validation_data=(X_val, y_val), epochs=30, batch_size=128, shuffle=False) #最小验证集 损失 val_loss = hist.history['val_loss'] index_min = np.argmin(val_loss) index_min ``` **结果输出:** 29 ```python import matplotlib.pyplot as plt import seaborn as sns plt.plot(hist.history['loss'], 'k', label='Training Loss') plt.plot(val_loss, 'b', label='Validation Loss') plt.axvline(index_min + 1, linestyle='--', color='k', linewidth=1) plt.xlabel('Epochs') plt.ylabel('Loss') plt.title('Training & Validation Loss') plt.legend() ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/026fe1530edd4023b189dbc885f511ad.png) ```python #最大 验证集 准确率 val_accuracy = hist.history['val_accuracy'] print(np.max(val_accuracy)) index_max = np.argmax(val_accuracy) print(index_max) ``` **结果输出:** 0.6206666827201843 29 ```python plt.plot(hist.history['accuracy'], 'k', label='Training Accuracy') plt.plot(val_accuracy, 'b', label='Validation Accuracy') plt.axvline(index_max, linestyle='--', color='k', linewidth=1) plt.xlabel('Epochs') plt.ylabel('Accuracy') plt.title('Training & Validation Accuracy') plt.legend() ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/68159072dc944615a46574fe317e21d7.png) ### 3. 预测 \& 混淆函数 ```python #在测试集中预测 prob = model.predict(X_test) prob[0] ``` **结果输出:** array(\[0.13906164, 0.05508504, 0.10248709, 0.10933477, 0.08082315, 0.10300557, 0.09999418, 0.11173221, 0.087742 , 0.11073436\], dtype=float32) ```python # 获取每个样本的类别索引 pred = np.argmax(prob, axis=1) pred[:5] ``` **结果输出:** array(\[0, 2, 0, 9, 3\], dtype=int64) ```python #混淆矩阵 from sklearn.metrics import confusion_matrix table = confusion_matrix(y_test_original, pred) table ``` array(\[\[376, 0, 4, 7, 0, 0, 4, 1, 0, 0\], \[ 0, 395, 22, 14, 0, 0, 1, 0, 22, 0\], \[ 33, 0, 273, 62, 1, 0, 15, 0, 9, 20\], \[ 11, 1, 13, 353, 1, 0, 1, 3, 11, 10\], \[ 7, 0, 3, 0, 227, 0, 3, 0, 4, 149\], \[ 35, 4, 2, 137, 10, 94, 1, 2, 31, 41\], \[ 98, 0, 5, 3, 7, 2, 242, 0, 11, 15\], \[ 4, 6, 15, 3, 2, 0, 0, 168, 8, 205\], \[ 22, 2, 12, 94, 4, 1, 1, 0, 208, 46\], \[ 10, 2, 5, 7, 8, 1, 0, 0, 3, 367\]\], dtype=int64) ```python #热力图 sns.heatmap(table, cmap = 'Blues', annot = True, fmt ='d') plt.xlabel('predicted') plt.ylabel('ture') plt.title('confusion_matrix') ``` ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/fba14ca8e08f498583aa5cd98939110b.png) *** ** * ** *** ## 附:系列文章目录 ### 监督学习:参数方法 [【学习笔记】 陈强-机器学习-Python-Ch4 线性回归](https://blog.csdn.net/2201_76026029/article/details/140833901) [【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归](https://blog.csdn.net/2201_76026029/article/details/140948506) [【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv)](https://blog.csdn.net/2201_76026029/article/details/141067852) [【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归](https://blog.csdn.net/2201_76026029/article/details/141094019) [【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析](https://blog.csdn.net/2201_76026029/article/details/141134271) [【学习笔记】 陈强-机器学习-Python-Ch8 朴素贝叶斯](https://blog.csdn.net/2201_76026029/article/details/141142107) [【学习笔记】 陈强-机器学习-Python-Ch9 惩罚回归](https://blog.csdn.net/2201_76026029/article/details/141186749) [【课后题练习】 陈强-机器学习-Python-Ch9 惩罚回归(student-mat.csv)](https://blog.csdn.net/2201_76026029/article/details/141215818) ### 监督学习:非参数方法 [【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch10 KNN法](https://blog.csdn.net/2201_76026029/article/details/141334765) [【学习笔记】 陈强-机器学习-Python-Ch11 决策树(Decision Tree)](https://blog.csdn.net/2201_76026029/article/details/141393002) ### 监督学习:集成学习 [【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch12 随机森林(Random Forest)](https://blog.csdn.net/2201_76026029/article/details/141559115) [【学习笔记】 陈强-机器学习-Python-Ch13 提升法](https://blog.csdn.net/2201_76026029/article/details/141559055) ### 监督学习:支持向量机 [【学习笔记】 陈强-机器学习-Python-Ch14 支持向量机](https://blog.csdn.net/2201_76026029/article/details/141649238) ### 监督学习:神经网络 [【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn](https://blog.csdn.net/2201_76026029/article/details/141996840?utm_medium=notify.im.blog_flow_coupon3.20240909.a&username=2201_76026029)

相关推荐
pop_xiaoli23 分钟前
OC—UI学习-2
学习·ui·ios
Lin Hsüeh-ch'in26 分钟前
Vue 学习路线图(从零到实战)
前端·vue.js·学习
恰薯条的屑海鸥1 小时前
零基础在实践中学习网络安全-皮卡丘靶场(第十五期-URL重定向模块)
学习·安全·web安全·渗透测试·网络安全学习
Eiceblue2 小时前
Python读取PDF:文本、图片与文档属性
数据库·python·pdf
自小吃多2 小时前
STC8H系列 驱动步进电机
笔记·单片机
weixin_527550402 小时前
初级程序员入门指南
javascript·python·算法
程序员的世界你不懂2 小时前
Appium+python自动化(十)- 元素定位
python·appium·自动化
CryptoPP3 小时前
使用WebSocket实时获取印度股票数据源(无调用次数限制)实战
后端·python·websocket·网络协议·区块链
树叶@3 小时前
Python数据分析7
开发语言·python
moxiaoran57533 小时前
uni-app学习笔记三十--request网络请求传参
笔记·学习·uni-app