教程地址:

  1. up:炮哥带你学

课程名字:[手把手教学]快速带你入门深度学习与实战

简介:入门机器学习和深度学习

网址:

https://www.bilibili.com/video/BV1eP411w7Re/?spm_id_from=333.1387.homepage.video_card.click&vd_source=f8d1f5518d3f58b48b5c428323f8d3bf

  1. up:炮哥带你学

课程名字:Pytorch框架与经典卷积神经网络与实战

简介:入门深度学习和pytorch

网址:

https://www.bilibili.com/video/BV1e34y1M7wR/?spm_id_from=333.1387.homepage.video_card.click&vd_source=f8d1f5518d3f58b48b5c428323f8d3bf

简介

深度学习以神经网络为基础

神经网络

  • 并非隐藏层越多越好 可能过拟合

全连接神经网络

通过训练w和b(权重和偏置)

  • 注:机器学习内容

神经网络作用

==深度学习框架介绍==

环境介绍

机器学习知识回顾

2. 线性回归模型与梯度下降

2.2 定义

  • x是特征 y是标签

损失函数 (误差函数)

穷举法

  • 过于垃圾 看后面最小二乘法
image-20250918134858646

2.3 最小二乘法

对x求偏导

向量版本

  • 损失函数
  • 更正 此处J(W)为f(x)
  • 对损失函数求导
  • 并非所有矩阵有可逆矩阵,因此引入损失函数
image-20250918141656527

==2.3 梯度下降==

理解

公式

$$
w=w-a \frac{\partial J(w)}{\partial w}
$$

  • 对多个w重复计算
  • 简化版本

  • $$
    \begin{array}{l}
    \text { repeat until convergence { }\
    \begin{aligned}
    w & =w-\alpha \frac{1}{m} \sum_{i=1}^{m}\left(f_{w, b}\left(x^{(i)}\right)-y^{(i)}\right) x^{(i)} \
    b & =b-\alpha \frac{1}{m} \sum_{i=1}^{m}\left(f_{w, b}\left(x^{(i)}\right)-y^{(i)}\right)
    \end{aligned}
    \end{array}
    $$

image-20250918153859855

案例

实战案例

步骤:

  1. 数据
  2. 模型
  3. 损失函数
  4. 梯度求导
  5. 利用梯度更新参数
  6. 设置训练轮次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 定义数据集

# 定义数据特征
x_data = [1, 2, 3]

# 定义数据标签
y_data = [2, 4, 6]

# 初始化w参数
w = 4


# 定义线性回归的模型
def forword(x):
return x * w


# 定义损失函数
def cost(xs, ys):
costvalue = 0
for x, y in zip(xs, ys):
y_pred = forword(x)
costvalue += (y_pred - y) ** 2
return costvalue / len(xs)


# 定义计算梯度的函数
def gradient(xs, ys):
grad = 0
for x, y in zip(xs, ys):
grad += 2 * x * (forword(x) - y)
return grad / len(xs)


# 学习率
aa = 0.01

for epoch in range(100):
cost_val = cost(x_data, y_data)
gra_val = gradient(x_data, y_data)
w = w - aa * gra_val
print('训练轮次:', epoch, 'w=', w, 'loss:', cost_val)

print('100轮后w已经训练好了', 'w=', w)
print("学习4小时最终得分为:", forword(4))

==3.逻辑回归==

3.1 回归和分类的区别

3.2 sigmoid函数

求导

image-20250919123351303

==3.3 损失函数==

表达式

==3.4 梯度下降==

image-20250919124419231

参数w更新

  • 向量求导
  • 带入函数常规求导推导:

参数b更新

3.5 回归模型评价指标

案例

准确率

精确率

召回率

F1值

image-20250919130914372

3.6 分类模型评价指标

平均绝对误差(MAE)和==均方误差(MSE)==

MSE 就是前面的LOSS 损失函数

均方根误差(RMSE)

平均绝对百分比误差(MAPE)

3.7 实战案例

代码

  1. 归一化公式:(X-min)/(max-min),消除量纲和数值大小对结果的影响
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

# 1. 读取数据
dataset = pd.read_csv("breast_cancer_data.csv")
# print(dataset)

# 2.提取特征x
X = dataset.iloc[:, :-1] # 除了最后一列
# print(x)

# 3.提取数据中的标签
Y = dataset['target']
# print(y)

# 4.划分数据集和测试集 八份训练集 二份测试集 随机抽取
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2)

# 5. 数据归一化 使数据在0~1之间 消除量纲影响
sc = MinMaxScaler(feature_range=(0, 1))
x_train = sc.fit_transform(x_train)
x_test = sc.transform(x_test)
# print(x_train)
# print(x_test)

# 6.逻辑回归模型搭建
lr = LogisticRegression()
lr.fit(x_train, y_train)

# 7.打印参数w和b
print("w", lr.coef_)
print("b", lr.intercept_)

# 8. 用训练好的模型推理测试
pre_result = lr.predict(x_test)
print("预测结果:", pre_result)

# 9.打印预测结果的概率
pre_result_proba = lr.predict_proba(x_test)
print("概率:", pre_result_proba)

# 10.获取恶性肿瘤的概率
pre_list = pre_result_proba[:, 1]
print(pre_list)

# 11. 设置保存结果的列表
result = []
result_name = []

# 设置阈值
thresholds = 0.3

for i in range(len(pre_list)):
if pre_list[i] > thresholds:
result.append(1)
result_name.append("恶性")
else:
result.append(0)
result_name.append("良性")

# 打印阈值调整后结果
print("打印阈值调整后结果:")
print(result)
print(result_name)

# 输出结果的精确率和召回还有f1值
print(y_test)
report = classification_report(y_test, result, labels=[0, 1], target_names=['良性肿瘤', '恶性肿瘤'])
print("输出结果的精确率和召回还有f1值--")
print(report)

结果打印

深度学习

全连接神经网络

结构

结构单元

  • 类比机器学习回归模型
  1. x 输入
  2. b 偏置
  3. w权重
  4. 求和:隐藏层
  5. 激活函数:非线性 ==(对比逻辑回归激活函数是求和 逻辑回归激活函数是sigmoid)==

对比机器学习激活函数

  • 对比逻辑回归激活函数是求和 逻辑回归激活函数是sigmoid)

激活函数作用

  • 非线性:这样最后就不会得到c的三次方为常数

激活函数

CSDN: 激活函数图像大全

https://blog.csdn.net/hy592070616/article/details/120617490

sigmoid函数

  • 梯度消失问题,倒数图像左右消失太快 w累计乘法后小数累成 趋近于0

Tanh函数(双曲正切函数)

数学知识

知乎:https://zhuanlan.zhihu.com/p/563840693

双曲正弦、双曲余弦、双曲正切基础知识整理

ReLU函数

  • 神经元死亡:z<0 倒数为0 w停止更新

Leaky ReLU

  • 没有最好的激活函数 只有符合的激活函数

SoftMax

  • 用于多分类任务
  • 用于输出层

前向传播

  1. 前向传播计算 预设w和b 根据数据集计算
  2. 计算误差 类比损失函数
  3. 计算梯度 梯度更新 求损失函数偏导
  4. 反向传播 反向更新w和b

具体过程

损失函数

  • 图像解释:前面cost值逐渐减小,w,b逐渐吻合,前向传播过程,用的train训练集

  • 后面趋近于0 可能是测试集test

链式法则(数学补充)

单变量链式法则

多变量链式发展

==反向传播==

案例

求解参数梯度

利用梯度参数更新

  • 设置学习率为0.1

新参数前向传播

案例(预测乳腺癌 分类)

  • 用全连接神经网络预测乳腺癌
  • 对比机器学习

model_train

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import keras
from keras.layers import Dense # 稠密层
from keras.utils.np_utils import to_categorical
from sklearn.metrics import classification_report # 验证
import matplotlib.font_manager as font_manager



# 解决中文显示问题
# font_path = '../SimHei.ttf' # 将此路径替换为你自己的 SimHei 字体文件的实际路径,也就是刚刚第二步得到的那个路径
# font_manager.fontManager.addfont(font_path)
# plt.rcParams['font.sans-serif'] = ['SimHei']
# plt.rcParams['axes.unicode_minus'] = False

# 111111111111111111111111 数据预处理 1111111111111111111111111111111111111111111111
# 加载数据集
dataset = pd.read_csv("breast_cancer_data.csv")

# 提取特征和标签
X = dataset.iloc[:, :-1]
Y = dataset['target']

# 划分训练集和测试集 random_state随机种子固定 保证每次数据随机一样
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=42)

# 将数据标签转为one-hot 独热向量格式
y_train_one = to_categorical(y_train, 2) # 2个类别
y_test_one = to_categorical(y_test, 2)
# print(y_train_one) # [1. 0.]

# 将数据特征归一化
sc = MinMaxScaler(feature_range=(0, 1))
x_train = sc.fit_transform(x_train)
x_test = sc.fit_transform(x_test)

# 22222222222222222222 用keras框架搭建深度学习神经网络模型 22222222222222222222222222222222222222222222
model = keras.Sequential()
model.add(Dense(10, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(2, activation='softmax'))

# 对神经网络进行编译 损失函数+评价指标
# categorical_crossentropy:交叉熵
# optimizer优化器:SGD随机梯度向量法
# metrics:评价指标 准确率
model.compile(loss='categorical_crossentropy', optimizer='SGD', metrics=['accuracy'])

# epochs轮数
# batch_size一次多少个一起 并行
# verbose 2表示控制台可观察
# validation_data验证数据 用测试集验证 框架用于判断是否过拟合
history = model.fit(x_train, y_train_one, epochs=120, batch_size=64, verbose=2, validation_data=(x_test, y_test_one))
model.save('model.h5')

# 333333333333333333333 绘图 333333333333333333333333333333
plt.plot(history.history['loss'], label='train') # 训练集loss值
plt.plot(history.history['val_loss'], label='val') # 验证集loss值
plt.title("全连接神经网络loss值图")
plt.legend() # 图例
plt.show()

# 绘制训练集和验证集的准确率对比图
plt.plot(history.history['accuracy'], label='train') # 训练集准确率
plt.plot(history.history['val_accuracy'], label='val') # 验证集准确率
plt.title("全连接神经网络accuracy值图")
plt.legend() # 图例
plt.show()

model_test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from cProfile import label

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import keras
from keras.layers import Dense # 稠密层
from keras.utils.np_utils import to_categorical
from sklearn.metrics import classification_report # 验证
import matplotlib.font_manager as font_manager
from keras.models import load_model

# 111111111111111111111111 数据预处理 1111111111111111111111111111111111111111111111
# 加载数据集
dataset = pd.read_csv("breast_cancer_data.csv")

# 提取特征和标签
X = dataset.iloc[:, :-1]
Y = dataset['target']

# 划分训练集和测试集 random_state随机种子固定 保证每次数据随机一样
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=42)

# 将数据标签转为one-hot 独热向量格式
y_test_one = to_categorical(y_test, 2)
# print(y_train_one) # [1. 0.]

# 将数据特征归一化
sc = MinMaxScaler(feature_range=(0, 1))
x_test = sc.fit_transform(x_test)

# 导入模型
model = load_model("model.h5")

# 利用训练好的模型进行测试
predict = model.predict(x_test)
# print(predict)

y_pred = np.argmax(predict, axis=1)
print(y_pred) # [0,1,0]

# 转为汉字
result = []
for i in range(len(y_pred)):
if y_pred[i] == 0:
result.append("良性")
else:
result.append("恶性")
print(result)

# 打印模型精确到 召回率
report = classification_report(y_test, y_pred, labels=[0, 1], target_names=["良性", "恶性"])
print(report)

函数图像

loss

plot_2025-09-21 16-31-23_0

accuracy

plot_2025-09-21 16-31-23_1

预测报告

image-20250921165430933

案例(空气质量 线性回归)

model_train

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import keras
from keras.layers import Dense # 稠密层
from keras.utils.np_utils import to_categorical

# 11111111111111111111111111 数据处理 1111111111111111111111
# 导入数据
dataset = pd.read_csv("data.csv")

# 将数据归一化
sc = MinMaxScaler(feature_range=(0, 1))
scaled = sc.fit_transform(dataset) # 数列形式 没有列名

# 将归一化数据转为dataframe格式,方便后续处理
dataset_sc = pd.DataFrame(scaled) # 有类名 同dataset
print(dataset_sc)

# 找出特征值和标签
X = dataset_sc.iloc[:, :-1] # 所有行除了最后一列
Y = dataset_sc.iloc[:, -1] # 所有行 最后一列

x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=42)

# 22222222222222222222222 利用keras模型搭建 2222222222222222222222222222222222
model = keras.Sequential()
model.add(Dense(10, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1)) # 输出层 不要激活函数 但要反归一化

# 对神经网络进行编译
model.compile(loss='mse', optimizer='SGD')

# 模型训练
history = model.fit(x_train, y_train, epochs=100, batch_size=32, verbose=2, validation_data=(x_test, y_test))
model.save('model.h5')

# 333333333333333333 可视化 3333333333333333
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='val')
plt.title("全连接神经网络loss值图")
plt.legend()
plt.show()

model_test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.ndimage import label
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import keras
from keras.layers import Dense # 稠密层
from keras.utils.np_utils import to_categorical
from keras.models import load_model
from math import sqrt
from numpy import concatenate
from sklearn.metrics import mean_squared_error

# 11111111111111111111111111 数据处理 1111111111111111111111
# 导入数据
dataset = pd.read_csv("data.csv")

# 将数据归一化
sc = MinMaxScaler(feature_range=(0, 1))
scaled = sc.fit_transform(dataset) # 数列形式 没有列名

# 将归一化数据转为dataframe格式,方便后续处理
dataset_sc = pd.DataFrame(scaled) # 有类名 同dataset

# 找出特征值和标签
X = dataset_sc.iloc[:, :-1] # 所有行除了最后一列
Y = dataset_sc.iloc[:, -1] # 所有行 最后一列

x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.05, random_state=42)

# 2222222222222 加载训练好的模型 222222222222222222
model = load_model("model.h5")

# 预测
yhat = model.predict(x_test)
# print(yhat) # [0.1681547 ]

# 预测值反归一化
inv_yhat = concatenate((x_test, yhat), axis=1) # 连接两个Numpy数据
# print(inv_yhat) # 归一数据 [0.05119454 0.09076175 0.06796117 ... 0.14107884 0.56149733 0.13507885]
inv_yhat = sc.inverse_transform(inv_yhat) # 反归一化
# print(inv_yhat) [ 12. 24. 5. ... 1.57 7.
# 82.83994955]
prediction = inv_yhat[:, 6]
# print(prediction)

# 将y_test维度转换 二维
# 2396 0.117073
# 1407 0.146341
y_test = np.array(y_test) # [0.11707317 0.14634146]
y_test = np.reshape(y_test, (y_test.shape[0], 1)) # [[0.11707317 0.14634146]]

# 反向缩放真实值
# print(x_test) # 2396 0.051195 0.090762 0.067961 0.172414 0.141079 0.561497
inv_y = concatenate((x_test, y_test), axis=1)
print(inv_y)
inv_y = sc.inverse_transform(inv_y)
real = inv_y[:, 6]
print(real)

# 333333333333333 评价 333333333333333333
# 计算rmse和MAPE
remse = sqrt(mean_squared_error(real, prediction))
mape = np.mean(np.abs(real - prediction) / real)
print("remse", remse)
print("mape", mape)

# 画出真实值和预测值对比图
plt.plot(prediction, label="预测值")
plt.plot(real, label="真实值")
plt.title("全连接神经网络空气质量预测对比图")
plt.legend()
plt.show()

loss图像

loss

真实值预测值对比图

对比图

卷积神经网络CNN

计算机图片本质(引入)

image-20250922170116085

整体结构

  • 卷积层:可以改变层数
  • 池化层:可以改变高度

卷积运算和权重共享

  • 对应位置相乘
    • 如第一行:0*0 + 1 * 1+ 3*2+3*4
  • 加入偏置
  • ==权重共享==
    • 矩阵中的数字有重叠w的情况
    • 九个数据在全连接神经网络有36个w,在卷积神经网络有4个w,有效解决过拟合问题
    • 在循环神经网络RNN也设计权重共享

填充运算和步幅运算

  1. 填充运算
    1. 原本矩阵3*3
    2. 在外面一层扩充0像素 5*5
    3. 5*5 像素做乘法得到 4*4
  1. 步幅
    1. 上面的计算默认步幅为1
    2. 可以调整步幅,如此时调整为2
    3. 4*4 * 2*2 得到 2*2 (步幅为2)
  1. 公式
    1. H 高
    2. P 填充高度
    3. FH 核的高度
    4. S 步幅
    5. OH 输出高度
    6. OW 输出宽度

多通道卷积运算

  • 对应的卷积相乘
  • 再相加
  • 通道数(特征图数量)相同才能相乘
  • 最后得到的结果都是一张特征图
    • 若要得到n张特征图 需要n份核图

池化运算

最大池化

  • 本质: 在每组中取特殊值

平均池化

  • 一般来说,最大池化比平均池化用的多

池化公式

实战(LENET) 目标缺陷检测

  1. maps6@28x28 6个特征图 每张图28*28

model_train

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import pathlib
import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPool2D

# 读取训练集数据
data_train = './data/train/'
data_train = pathlib.Path(data_train)

data_val = './data/val/'
data_val = pathlib.Path(data_train)

# 给出局类别放置到列表数据中
CLASS_NAMES = np.array(['Cr', 'In', 'Pa', 'PS', 'Rs', 'Sc'])

# 设置图片大小和批次数
BATCH_SIZE = 64 # 每次训练一批数据量
# 一张图片大小
IMG_HEIGHT = 32
IMG_WIDTH = 32

# 对数据进行归一化处理
image_generator = keras.preprocessing.image.ImageDataGenerator(rescale=1.0 / 255)

# 训练集生成器 生成一批数据
train_data_gen = image_generator.flow_from_directory(directory=str(data_train),
batch_size=BATCH_SIZE,
shuffle=True,
target_size=(IMG_HEIGHT, IMG_WIDTH), # 压缩
classes=list(CLASS_NAMES)
)
# 验证集生成器
val_data_gen = image_generator.flow_from_directory(directory=str(data_val),
batch_size=BATCH_SIZE,
shuffle=True,
target_size=(IMG_HEIGHT, IMG_WIDTH),
classes=list(CLASS_NAMES)
)

# 利用keras搭建卷积神经网络
model = keras.Sequential()
model.add(Conv2D(filters=6, kernel_size=5, input_shape=(32, 32, 3), activation='relu')) # 卷积
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2))) # 池化
model.add(Conv2D(filters=16, kernel_size=5, activation='relu')) # 卷积
model.add(MaxPool2D(pool_size=(2, 2), strides=(2, 2))) # 池化
model.add(Conv2D(filters=120, kernel_size=5, activation='relu')) # 卷积
model.add(Flatten()) # 平展曾
model.add(Dense(84, activation='relu')) # 全连接层
model.add(Dense(6, activation='softmax')) # 输出层 6分类

# 编译卷积神经网络
model.compile(loss='binary_crossentropy', optimizer='Adam', metrics=['accuracy'])

# 传入数据集进行训练
history = model.fit(train_data_gen, validation_data=val_data_gen, epochs=50)

# 保存训练好的模型
model.save("model.h5")

# 绘制loss图
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='val')
plt.title("CNN神经网络loss值")
plt.legend()
plt.show()

# 绘制准确率
plt.plot(history.history['accuracy'], label='train')
plt.plot(history.history['val_accuracy'], label='val')
plt.title("CNN神经网络accuracy值")
plt.legend()
plt.show()

model_test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import numpy as np
import tensorflow as tf
from keras.models import load_model
import cv2

# 给数据类别放置到列表数据中
CLASS_NAMES = np.array(['Cr', 'In', 'Pa', 'PS', 'Rs', 'Sc'])


# 设置图片大小
IMG_HEIGHT = 32
IM_WIDTH = 32

# 加载模型
model = load_model("model.h5")

# 数据读取与预处理
src = cv2.imread("data/val/Cr/Cr_48.bmp") # 挑取一张图片
src = cv2.resize(src, (32, 32)) # 压缩图片32*32
src = src.astype("int32") # 转为int型
src = src / 255 # 归一化

# 扩充数据的维度
test_img = tf.expand_dims(src, 0)
# print(test_img.shape)

preds = model.predict(test_img)
# print(preds)
score = preds[0]
# print(score)

print('模型预测的结果为{}, 概率为{}'.format(CLASS_NAMES[np.argmax(score)], np.max(score)))

循环神经网络

RNN

RNN基本结构

  1. h0不仅作为第一个隐藏层输出 也作为第二个隐藏层输入
  2. 先计算t0时刻,接着t1。有先后顺序
    1. CNN则是同时输入 只有空间维度
    2. RNN加入时间维度,受之前数据影响

RNN和全连接神经网络区别

  1. 去掉W和全连接神经网络一样
全连接展开
RNN展开
  • 前一个时刻hw + 后面时刻hU

数学模型及权重共享

  • 每个时刻对应的权重w和v相同

前向传播案例

第一个时间步
第二个时间步

反向传播

梯度消失和梯度爆炸

公式
原因
  1. 假设这里使用sigmoid函数
  2. 求导后为 f*(1-f)
  3. f=0.5 有最大值1/4
  4. w共享:
    1. 所以当w<4 第一个h倒数小于1 累成 梯度消失 (很难学到前面很长时间的权重 LSTM有缓解)
    2. 所以当w>4 第一个h倒数大于1 累成 梯度爆炸💥

==LSTM==

和RNN对比

基本结构

基本运算

  1. 黄色方框都是激活函数
    1. 有sigmoid和tanh反双曲正切

遗忘门

  • 作用:保存有用信息,摒弃没用的信息
    • sigmoid 函数将值域映射在0~1
    • Wf 是权重

输入门

结构
细胞状态更新

输出门

如何缓解梯度消失

公式对比
求导
  • 对Ct-1 求导

实战(黄金价格预测)

  1. 单特征情况
    1. 时间 价格变为多特征
    2. 前五天预测第六天 滚动预测
    3. 时间步为5
model_train
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# 导入库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from tensorflow import keras
from keras.layers import Dense, LSTM, Flatten

# 111111111111111111111111111111111数据处理111111111111111111111111111111111

# 加载数据集 第0列当做索引
dateset = pd.read_csv("LBMA-GOLD.csv", index_col=0)
# print(dateset)

# 设置训练集长度
training_len = 1265 - 200

# 获取训练集 第零行到训练集 所有列
training_set = dateset.iloc[:training_len, :]

# 获取测试集数据
test_set = dateset.iloc[training_len:, :]
# print(training_set)
# print(test_set)

# 对数据集进行归一化
sc = MinMaxScaler(feature_range=(0, 1))
train_set_scaled = sc.fit_transform(training_set)
test_set = sc.fit_transform(test_set)

# 设置训练集特征和标签
x_train = []
y_train = []

# 设置测试集特征和标签
x_test = []
y_test = []

# 利用for循环,遍历整个训练集,提取训练集中连续5个采样点的数据作为输入特征x_train,第6个采样点的数据作为标签.
for i in range(5, len(train_set_scaled)):
x_train.append(train_set_scaled[i - 5:i, 0]) # [0~5) 1~6.....第一列 特征值
y_train.append(train_set_scaled[i, 0]) # [5]标签


# 将训练集由list格式变为array格式
x_train, y_train = np.array(x_train), np.array(y_train)


# 使x_train符合输入要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]。
# 此处整个数据集送入,送入样本数为x_train.shape[0]即训练数据的样本个数; 循环核时间展开步数定位5
x_train = np.reshape(x_train, (x_train.shape[0], 5, 1))
print(x_train)
# [[[0.21126985]
# [0.21026077]
# [0.2082426 ]
# [0.19661161]
# [0.19400924]]

# 同理划分测试集数据
for i in range(5, len(test_set)):
x_test.append(test_set[i - 5:i, 0])
y_test.append(test_set[i, 0])


# 测试集变array并reshape为符合要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]
x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (x_test.shape[0], 5, 1))

# 22222222222222222222222222222222222222搭建网络222222222222222222222222222222222
# # 搭建神经网络模型
model = keras.Sequential()
model.add(LSTM(80, return_sequences=True, activation="relu"))
model.add(LSTM(100, return_sequences=False, activation="relu"))
model.add(Dense(10, activation="relu")) # 全连接层
model.add(Dense(1)) # 输出层


# 对模型进行编译,选用学习率为0.01
model.compile(loss='mse', optimizer=keras.optimizers.SGD(0.01))

# 将训练集和测试集放入网络进行训练,每批次送入的数据为32个数据,一共训练50轮,将测试集样本放入到神经网络中测试其验证集的loss值
history = model.fit(x_train, y_train, batch_size=32, epochs=100, validation_data=(x_test, y_test))
model.save('model.h5')

# 3333333333333333333333333333333333画图33333333333333333333333333333333333333333333

# 绘制训练集和测试集的loss值对比图
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='val')
plt.title("LSTM神经网络loss值")
plt.legend()
plt.show()
model_test
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# 导入库
import pandas as pd
import numpy as np
import matplotlib.pyplot
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from math import sqrt
from keras.models import load_model
import matplotlib.pyplot as plt

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 加载历史数据文件
dataset = pd.read_csv('LBMA-GOLD.csv', index_col='Date')
# print(dataset)

# 设置训练集的长度
training_len = 1256 -200


# 获取测试集数据
test_set = dataset.iloc[training_len:, [0]]

# 将数据集进行归一化,方便神经网络的训练
sc = MinMaxScaler(feature_range=(0, 1))
test_set = sc.fit_transform(test_set)


# 设置放置测试数据特征和测试数据标签的列表
x_test = []
y_test = []



# 同理划分测试集数据
for i in range(5, len(test_set)):
x_test.append(test_set[i - 5:i, 0])
y_test.append(test_set[i, 0])


# 测试集变array并reshape为符合要求:[送入样本数, 循环核时间展开步数, 每个时间步输入特征个数]
x_test, y_test = np.array(x_test), np.array(y_test)
x_test = np.reshape(x_test, (x_test.shape[0], 5, 1))

# 导入模型
model = load_model('model.h5')


# 利用模型进行测试
predicted = model.predict(x_test)
# print(predicted.shape)

# 进行预测值的反归一化
prediction = sc.inverse_transform(predicted)
# print(prediction)

# 对测试集的标签进行反归一化

real = sc.inverse_transform(test_set[5:])
# print(real)


# 打印模型的评价指标
rmse = sqrt(mean_squared_error(prediction, real))
mape = np.mean(np.abs((real-prediction)/prediction))
print('rmse', rmse)
print('mape', mape)

# 绘制真实值和预测值的对比
plt.plot(real, label='真实值')
plt.plot(prediction, label='预测值')
plt.title("基于LSTM神经网络的黄金价格预测")
plt.legend()
plt.show()