深度学习基础:神经网络原理 深度学习是人工智能的核心技术,本文系统讲解神经网络的基础原理和关键概念。 感知机与神经元 基本单元 多层感知机 反向传播 损失函数 梯度计算 优化算法 SGD Adam优化器 正则化 Dropout Batch Normalization 卷积神经网络 卷积层 池化层 CNN架构示例 通过理解这些基础概念,可以构建各种深度学习模型,解决图像识别、自然语言处理等复杂问题。
深度学习是人工智能的核心技术,本文系统讲解神经网络的基础原理和关键概念。
# 单个神经元 class Neuron: def __init__(self, input_size): # 权重和偏置 self.weights = np.random.randn(input_size) self.bias = np.random.randn() def forward(self, x): # 加权求和 z = np.dot(x, self.weights) + self.bias # 激活函数 a = self.sigmoid(z) return a def sigmoid(self, z): return 1 / (1 + np.exp(-z))
# 全连接层 class DenseLayer: def __init__(self, input_size, output_size): self.W = np.random.randn(input_size, output_size) * 0.01 self.b = np.zeros(output_size) def forward(self, X): # X: [batch_size, input_size] self.Z = np.dot(X, self.W) + self.b self.A = self.relu(self.Z) return self.A def relu(self, Z): return np.maximum(0, Z) # 简单的神经网络 class NeuralNetwork: def __init__(self): self.layer1 = DenseLayer(784, 128) self.layer2 = DenseLayer(128, 64) self.layer3 = DenseLayer(64, 10) def forward(self, X): A1 = self.layer1.forward(X) A2 = self.layer2.forward(A1) A3 = self.layer3.forward(A2) return A3
# 分类交叉熵损失 def cross_entropy_loss(y_pred, y_true): # y_pred: [batch, num_classes] (softmax输出) # y_true: [batch, num_classes] (one-hot) # 避免log(0) epsilon = 1e-15 y_pred = np.clip(y_pred, epsilon, 1 - epsilon) # 计算损失 loss = -np.sum(y_true * np.log(y_pred)) / y_pred.shape[0] return loss # Softmax函数 def softmax(Z): exp_Z = np.exp(Z - np.max(Z, axis=1, keepdims=True)) return exp_Z / np.sum(exp_Z, axis=1, keepdims=True)
# 反向传播 def backward(self, X, y, learning_rate=0.01): # 前向传播 A1 = self.layer1.forward(X) A2 = self.layer2.forward(A1) Z3 = self.layer3.Z A3 = softmax(Z3) # 计算输出层梯度 dZ3 = A3 - y # [batch, 10] dW3 = np.dot(A2.T, dZ3) / X.shape[0] db3 = np.mean(dZ3, axis=0) # 反向传播到layer2 dA2 = np.dot(dZ3, self.layer3.W.T) dZ2 = dA2 * (self.layer2.A > 0) # ReLU导数 dW2 = np.dot(A1.T, dZ2) / X.shape[0] db2 = np.mean(dZ2, axis=0) # 反向传播到layer1 dA1 = np.dot(dZ2, self.layer2.W.T) dZ1 = dA1 * (self.layer1.A > 0) dW1 = np.dot(X.T, dZ1) / X.shape[0] db1 = np.mean(dZ1, axis=0) # 更新参数 self.layer1.W -= learning_rate * dW1 self.layer1.b -= learning_rate * db1 self.layer2.W -= learning_rate * dW2 self.layer2.b -= learning_rate * db2 self.layer3.W -= learning_rate * dW3 self.layer3.b -= learning_rate * db3
# 随机梯度下降 def sgd_update(params, grads, learning_rate): for param, grad in zip(params, grads): param -= learning_rate * grad
class Adam: def __init__(self, params, learning_rate=0.001): self.params = params self.lr = learning_rate self.beta1 = 0.9 self.beta2 = 0.999 self.epsilon = 1e-8 self.m = [np.zeros_like(p) for p in params] self.v = [np.zeros_like(p) for p in params] self.t = 0 def update(self, grads): self.t += 1 for i, (param, grad) in enumerate(zip(self.params, grads)): # 一阶矩估计 self.m[i] = self.beta1 * self.m[i] + (1 - self.beta1) * grad # 二阶矩估计 self.v[i] = self.beta2 * self.v[i] + (1 - self.beta2) * (grad ** 2) # 偏差修正 m_hat = self.m[i] / (1 - self.beta1 ** self.t) v_hat = self.v[i] / (1 - self.beta2 ** self.t) # 参数更新 param -= self.lr * m_hat / (np.sqrt(v_hat) + self.epsilon)
# Dropout层 class Dropout: def __init__(self, dropout_rate=0.5): self.dropout_rate = dropout_rate self.mask = None def forward(self, X, training=True): if training: # 生成随机mask self.mask = (np.random.rand(*X.shape) > self.dropout_rate).astype(float) # 应用mask并缩放 return X * self.mask / (1 - self.dropout_rate) else: return X def backward(self, dA): return dA * self.mask / (1 - self.dropout_rate)
# 批归一化 class BatchNorm: def __init__(self, num_features, epsilon=1e-5): self.gamma = np.ones(num_features) self.beta = np.zeros(num_features) self.epsilon = epsilon self.running_mean = np.zeros(num_features) self.running_var = np.ones(num_features) def forward(self, X, training=True): if training: # 计算批次统计量 mean = np.mean(X, axis=0) var = np.var(X, axis=0) # 更新运行统计量 self.running_mean = 0.9 * self.running_mean + 0.1 * mean self.running_var = 0.9 * self.running_var + 0.1 * var else: mean = self.running_mean var = self.running_var # 归一化 X_normalized = (X - mean) / np.sqrt(var + self.epsilon) # 缩放和平移 out = self.gamma * X_normalized + self.beta return out
# 2D卷积 class Conv2D: def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1): self.in_channels = in_channels self.out_channels = out_channels self.kernel_size = kernel_size self.stride = stride self.padding = padding # 卷积核 self.W = np.random.randn(out_channels, in_channels, kernel_size, kernel_size) * 0.01 self.b = np.zeros(out_channels) def forward(self, X): # X: [batch, in_channels, H, W] batch_size = X.shape[0] # 填充 if self.padding > 0: X = np.pad(X, ((0, 0), (0, 0), (self.padding, self.padding), (self.padding, self.padding))) # 输出尺寸 H_out = (X.shape[2] - self.kernel_size) // self.stride + 1 W_out = (X.shape[3] - self.kernel_size) // self.stride + 1 # 卷积操作 output = np.zeros((batch_size, self.out_channels, H_out, W_out)) for b in range(batch_size): for c in range(self.out_channels): for i in range(H_out): for j in range(W_out): # 提取patch patch = X[b, :, i*self.stride:i*self.stride+self.kernel_size, j*self.stride:j*self.stride+self.kernel_size] # 卷积 output[b, c, i, j] = np.sum(patch * self.W[c]) + self.b[c] return output
# 最大池化 class MaxPool2D: def __init__(self, kernel_size=2, stride=2): self.kernel_size = kernel_size self.stride = stride def forward(self, X): # X: [batch, channels, H, W] batch, channels, H, W = X.shape # 输出尺寸 H_out = (H - self.kernel_size) // self.stride + 1 W_out = (W - self.kernel_size) // self.stride + 1 output = np.zeros((batch, channels, H_out, W_out)) for b in range(batch): for c in range(channels): for i in range(H_out): for j in range(W_out): # 提取窗口并取最大值 window = X[b, c, i*self.stride:i*self.stride+self.kernel_size, j*self.stride:j*self.stride+self.kernel_size] output[b, c, i, j] = np.max(window) return output
# LeNet-5 class LeNet5: def __init__(self): self.conv1 = Conv2D(1, 6, kernel_size=5, padding=2) self.pool1 = MaxPool2D(kernel_size=2, stride=2) self.conv2 = Conv2D(6, 16, kernel_size=5) self.pool2 = MaxPool2D(kernel_size=2, stride=2) self.fc1 = DenseLayer(16 * 5 * 5, 120) self.fc2 = DenseLayer(120, 84) self.fc3 = DenseLayer(84, 10) def forward(self, X): # [batch, 1, 28, 28] X = self.pool1(relu(self.conv1.forward(X))) X = self.pool2(relu(self.conv2.forward(X))) X = X.reshape(X.shape[0], -1) X = relu(self.fc1.forward(X)) X = relu(self.fc2.forward(X)) X = self.fc3.forward(X) return softmax(X)
通过理解这些基础概念,可以构建各种深度学习模型,解决图像识别、自然语言处理等复杂问题。