Bootstrap

python编写一个简单神经网络计算代码带有反向传播,不用任何框架

以下是一个简单的神经网络计算代码,它由三个函数组成:init_network()、forward()和softmax()。这个神经网络有一个输入层、一个隐藏层和一个输出层,其中输入层和隐藏层都有三个神经元,输出层有两个神经元。

import numpy as np

def init_network():
    # 初始化权重和偏置
    network = {}
    network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
    network['b1'] = np.array([0.1, 0.2, 0.3])
    network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
    network['b2'] = np.array([0.1, 0.2])
    network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
    network['b3'] = np.array([0.1, 0.2])
    return network

def forward(network, x):
    # 前向传播
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']
    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = softmax(a3)
    return y

def sigmoid(x):
    # sigmoid函数
    return 1 / (1 + np.exp(-x))

def softmax(x):
    # softmax函数
    exp_x = np.exp(x)
    return exp_x / np.sum(exp_x)

# 测试
network = init_network()
x = np.array([1.0, 0.5])
y = forward(network, x)
print(y)

在上述代码中,init_network()函数用于初始化神经网络的权重和偏置,forward()函数用于进行前向传播计算,sigmoid()函数用于计算sigmoid函数,softmax()函数用于计算softmax函数。最后,我们通过调用init_network()和forward()函数来计算输入x=[1.0, 0.5]时的输出结果。输出结果是一个长度为2的数组,表示两个输出神经元的激活值,它们的和等于1.0,因为我们使用了softmax函数对输出进行归一化处理。

如果要使用反向传播算法来训练神经网络,需要在前向传播的基础上实现反向传播算法来计算权重和偏置的梯度,然后使用梯度下降法来更新权重和偏置。下面是一个简单的神经网络计算代码,其中包括前向传播、反向传播和梯度下降的实现:

import numpy as np

class TwoLayerNet:
    
    def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):
        # 初始化权重和偏置
        self.params = {}
        self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size)
        self.params['b2'] = np.zeros(output_size)
        
    def forward(self, x):
        # 前向传播
        W1, W2 = self.params['W1'], self.params['W2']
        b1, b2 = self.params['b1'], self.params['b2']
        a1 = np.dot(x, W1) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        y = softmax(a2)
        self.z = (x, a1, z1, a2)
        return y
    
    def backward(self, t):
        # 反向传播
        x, a1, z1, a2 = self.z
        grads = {}
        delta2 = (self.y - t)
        grads['W2'] = np.dot(z1.T, delta2)
        grads['b2'] = np.sum(delta2, axis=0)
        delta1 = np.dot(delta2, self.params['W2'].T) * sigmoid_grad(a1)
        grads['W1'] = np.dot(x.T, delta1)
        grads['b1'] = np.sum(delta1, axis=0)
        return grads
    
    def numerical_gradient(self, x, t):
        # 数值微分求梯度
        loss_W = lambda W: self.loss(x, t)
        grads = {}
        grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
        grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
        grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
        grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
        return grads
    
    def gradient(self, x, t):
        # 反向传播求梯度
        self.y = self.forward(x)
        grads = self.backward(t)
        return grads
    
    def train(self, x, t, learning_rate=0.1):
        # 训练
        grads = self.gradient(x, t)
        for key in ('W1', 'b1', 'W2', 'b2'):
            self.params[key] -= learning_rate * grads[key]
            
    def predict(self, x):
        # 预测
        y = self.forward(x)
        return np.argmax(y, axis=1)
    
    def accuracy(self, x, t):
        # 计算准确率
        y = self.predict(x)
        return np.mean(y == t)
    
    def loss(self, x, t):
        # 计算损失函数
        y = self.forward(x)
        return cross_entropy_error(y, t)

def sigmoid(x):
    # sigmoid函数
    return 1 / (1 + np.exp(-x))

def sigmoid_grad(x):
    # sigmoid函数的导数
    return (1.0 - sigmoid(x)) * sigmoid(x)

def softmax(x):
    # softmax函数
    exp_x = np.exp(x)
    return exp_x / np.sum(exp_x)

def cross_entropy_error(y, t):
    # 交叉熵误差
    delta = 1e-7
    return -np.sum(t * np.log(y + delta))

def numerical_gradient(f, x):
    # 数值微分
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)
    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
    while not it.finished:
        idx = it.multi_index
        tmp_val = x[idx]
        x[idx] = tmp_val + h
        fxh1 = f(x)
        x[idx] = tmp_val - h
        fxh2 = f(x)
        grad[idx] = (fxh1 - fxh2) / (2 * h)
        x[idx] = tmp_val
        it.iternext()
    return grad

以上代码实现了一个具有两个隐藏层的全连接神经网络,包含前向传播、反向传播、数值微分求梯度和梯度下降的实现。其中的参数初始化使用了高斯分布,激活函数使用了sigmoid函数,损失函数使用了交叉熵误差,优化算法使用了梯度下降。

python库的简单实例及介绍
python傻瓜式入门
人间清醒
量化交易策略介绍
linux系统相关 - 知乎 (zhihu.com)

Python如何调用pygame库来启动摄像头捕获图像并显示
python编写一段会跳动的文字
c#程序与USB HID设备进行通信
Python如何把sqlite完全加载到内存中操作
streamlit如何布局
Python的faker库,测试工作者的福音
Python程序如何进行性能分析
Python 如何使用dask库来并行化Pandas DataFrame
Python如何用Numba加速科学计算和数据分析
python 如何把多个列表合成一个
如何反汇编和分析Python字节码,了解代码的执行过程
python kaleido 库
Python如何把一个列表按照一定数量均匀的切片
python 非常好用的标准库itertools
Python pygame库开发的射击小游戏(二娃大战外星人)完整示例.
Python如何从新浪财经爬去分价表数据
如何将一个Sqlite数据库Db中的所有表快速拆分到多个db文件中
Python程序记日志竟如此简单
如何将Excel的列的字母编号转化为数字
QT C++的QDataStream的大坑

;