-
Notifications
You must be signed in to change notification settings - Fork 0
/
layers_1.py
73 lines (69 loc) · 3.07 KB
/
layers_1.py
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
# -*- 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
return self.output
def backward(self, top_diff): # 反向传播的计算
# TODO:全连接层的反向传播,计算参数梯度和本层损失
self.d_weight = np.dot(self.input.T, top_diff)
self.d_bias = np.sum(top_diff, axis=0)
bottom_diff = np.dot(top_diff, self.weight.T)
return bottom_diff
def update_param(self, lr): # 参数更新
# TODO:对全连接层参数利用参数进行更新
self.weight = self.weight - lr*self.d_weight
self.bias = 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, self.input)
return output
def backward(self, top_diff): # 反向传播的计算
# TODO:ReLU层的反向传播,计算本层损失
bottom_diff = top_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)
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) / self.batch_size
return bottom_diff