# coding=utf-8 import numpy as np import struct import os import time class FullyConnectedLayer(object): def __init__(self, num_input, num_output): # 全连接层初始化 self.num_input = num_input self.num_output = num_output print('\tFully connected layer with input %d, output %d.' % (self.num_input, self.num_output)) def init_param(self, std=0.01): # 参数初始化 self.weight = np.random.normal(loc=0.0, scale=std, size=(self.num_input, self.num_output)) self.bias = np.zeros([1, self.num_output]) def forward(self, input): # 前向传播计算 start_time = time.time() self.input = input # TODO:全连接层的前向传播,计算输出结果 self.output = np.dot(input, self.weight) + self.bias#y=wx+b return self.output def backward(self, top_diff): # 反向传播的计算 # TODO:全连接层的反向传播,计算参数梯度和本层损失 self.d_weight = np.dot(self.input.T, top_diff)#计算权重的梯度 d_weight self.d_bias = np.sum(top_diff, axis=0, keepdims=True)#计算偏置的梯度 d_bias bottom_diff = np.dot(top_diff, self.weight.T)#计算传递给下一层的误差梯度 bottom_diff return bottom_diff def update_param(self, lr): # 参数更新 # TODO:对全连接层参数利用参数进行更新 self.weight -= lr * self.d_weight#权重更新 self.bias -= lr * self.d_bias#偏置更新 def load_param(self, weight, bias): # 参数加载 assert self.weight.shape == weight.shape assert self.bias.shape == bias.shape self.weight = weight self.bias = bias def save_param(self): # 参数保存 return self.weight, self.bias class ReLULayer(object): def __init__(self): print('\tReLU layer.') def forward(self, input): # 前向传播的计算 start_time = time.time() self.input = input # TODO:ReLU层的前向传播,计算输出结果 output = np.maximum(0, input)#对于所有正数输入 x,输出为 x;对于所有非正数输入,输出为 0 return output def backward(self, top_diff): # 反向传播的计算 # TODO:ReLU层的反向传播,计算本层损失 bottom_diff = top_diff.copy()#创建 top_diff 的一个副本,并将该副本赋值给 bottom_diff bottom_diff[self.input<0] = 0 return bottom_diff class SoftmaxLossLayer(object): def __init__(self): print('\tSoftmax loss layer.') def forward(self, input): # 前向传播的计算 # TODO:softmax 损失层的前向传播,计算输出结果 input_max = np.max(input, axis=1, keepdims=True) input_exp = np.exp(input - input_max) self.prob = input_exp / np.sum(input_exp, axis=1, keepdims=True)#计算 Softmax 函数,将输入转换为概率分布 return self.prob def get_loss(self, label): # 计算损失 self.batch_size = self.prob.shape[0] self.label_onehot = np.zeros_like(self.prob) self.label_onehot[np.arange(self.batch_size), label] = 1.0 loss = -np.sum(np.log(self.prob) * self.label_onehot) / self.batch_size return loss def backward(self): # 反向传播的计算 # TODO:softmax 损失层的反向传播,计算本层损失 bottom_diff = self.prob - self.label_onehot#计算 Softmax 层输出的概率分布 self.prob 与真实标签 one-hot 编码 self.label_onehot 之间的差异 return bottom_diff
11-16
184

06-28
3140

11-11
2595

02-03
7273

10-21