Featured image of post RNN

RNN

纯废物,代码跑不了

一文读懂循环神经网络(RNN) - 知乎

  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
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import numpy as np
import matplotlib.pyplot as plt

# 时间序列
t = np.linspace(0, 10, 500)  # 0 到 10 秒,共 500 个点

# 生成波形
sine_wave = np.sin(2 * np.pi * t)  # 正弦波
square_wave = np.sign(np.sin(2 * np.pi * t))  # 方波
triangle_wave = 2 * np.abs(2 * (t % 1) - 1) - 1  # 三角波

# 添加噪声
noise = np.random.normal(0, 0.1, sine_wave.shape)  # 高斯噪声
sine_wave_noisy = sine_wave + noise
square_wave_noisy = square_wave + noise
triangle_wave_noisy = triangle_wave + noise

# 可视化,三个波形并排显示
fig, axs = plt.subplots(1, 3, figsize=(18, 5))

# 正弦波
axs[0].plot(t, sine_wave, label="Original Sine Wave")
axs[0].plot(t, sine_wave_noisy, label="Noisy Sine Wave", alpha=0.7)
axs[0].set_title("Sine Wave with Noise")
axs[0].legend()

# 方波
axs[1].plot(t, square_wave, label="Original Square Wave")
axs[1].plot(t, square_wave_noisy, label="Noisy Square Wave", alpha=0.7)
axs[1].set_title("Square Wave with Noise")
axs[1].legend()

# 三角波
axs[2].plot(t, triangle_wave, label="Original Triangle Wave")
axs[2].plot(t, triangle_wave_noisy, label="Noisy Triangle Wave", alpha=0.7)
axs[2].set_title("Triangle Wave with Noise")
axs[2].legend()

plt.tight_layout()
plt.show()

class RNN:
    def __init__(self, input_size, x_train, y_train, lr=0.01, max_iter=100):
        self.input_size = input_size
        self.x_train = x_train
        self.y_train = y_train
        self.y_cut_off = self.y_train[input_size:]
        self.wh = np.random.normal(0, 0.1, input_size-1)
        self.bh = np.random.normal(0, 0.1, input_size-1)
        self.wx = np.random.normal(0, 0.1, input_size)
        self.v = np.random.normal(0, 0.1)
        self.h = np.zeros(input_size)
        self.z = np.zeros(input_size)
        self.lr = lr
        self.max_iter = max_iter

    def train(self):
        iter_num = 0
        losses = []
        while iter_num < self.max_iter:
            y_predict = np.zeros(len(self.x_train) - self.input_size)
            for i in range(0, len(self.x_train) - self.input_size):
                x = self.x_train[i:i+self.input_size]
                self.z = self.wx * x
                self.h[0] = self.sig(self.z[0])
                for j in range(1, self.input_size):
                    self.z[j] += self.h[j-1] * self.wh[j-1] + self.bh[j-1]
                    self.h[j] = self.sig(self.z[j])
                y_hat = self.v * self.h[-1]
                y_predict[i] = y_hat
                y = self.y_cut_off[i]
                self.back_propagation(x, y_hat, y)
            loss = self.loss(y_predict)
            losses.append(loss)
            print(f"第{iter_num+1}轮训练,MSE损失为{loss}")
            iter_num += 1
        return y_predict, losses

    def sig(self, x):
        return 1 / (1 + np.exp(-x))

    def back_propagation(self, x, y_hat, y):
        dloss_dhi = np.zeros(self.input_size)
        dloss_dhi[-1] = (y_hat - y) * self.v
        for i in range(self.input_size - 2, -1, -1):
            dloss_dhi[i] = dloss_dhi[i + 1] * self.wh[i] * self.sig(self.z[i]) * (1 - self.sig(self.z[i]))
        dloss_dwh = dloss_dhi[1:] * self.sig(self.z[1:]) * (1 - self.sig(self.z[1:])) * self.h[:-1]
        dloss_dbh = dloss_dhi[1:] * self.sig(self.z[1:]) * (1 - self.sig(self.z[1:]))
        dloss_dwx = dloss_dhi * self.sig(self.z) * (1 - self.sig(self.z)) * x
        dloss_dv = (y_hat - y) * self.h[-1]
        self.wh -= self.lr * dloss_dwh
        self.bh -= self.lr * dloss_dbh
        self.wx -= self.lr * dloss_dwx
        self.v -= self.lr * dloss_dv

    def loss(self, y_predict):
        return 0.5 * np.sum((y_predict - self.y_cut_off) ** 2)

# 生成数据
t = np.linspace(0, 100, 200)
sine_wave = np.sin(40 * np.pi * t)/1000

# 创建并训练模型
r = RNN(10, t, sine_wave, lr=0.1, max_iter=1000)
y_pred, losses = r.train()

# 绘制损失曲线
plt.figure(figsize=(12, 5))
plt.plot(losses)
plt.title("Loss Curve")
plt.xlabel("Iteration")
plt.ylabel("MSE Loss")
plt.show()

# 绘制预测结果
plt.figure(figsize=(12, 5))
plt.plot(t[10:], r.y_cut_off, label="True")
plt.plot(t[10:], y_pred, label="Predicted")
plt.title("Prediction Results")
plt.xlabel("Time")
plt.ylabel("Amplitude")
plt.legend()
plt.show()
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计