Python实现CNN
时间: 2023-11-05 10:14:34 浏览: 93
下面是一个简单的Python实现CNN的示例代码:
```python
import numpy as np
# 定义卷积层
class ConvLayer:
def __init__(self, input_channels, num_filters, filter_size, stride, padding):
self.input_channels = input_channels
self.num_filters = num_filters
self.filter_size = filter_size
self.stride = stride
self.padding = padding
self.filters = np.random.randn(num_filters, input_channels, filter_size, filter_size) / (filter_size ** 2)
def forward(self, input):
self.input_shape = input.shape
batch_size, input_channels, input_height, input_width = self.input_shape
output_height = int((input_height + 2 * self.padding - self.filter_size) / self.stride + 1)
output_width = int((input_width + 2 * self.padding - self.filter_size) / self.stride + 1)
self.output_shape = (batch_size, self.num_filters, output_height, output_width)
self.output = np.zeros(self.output_shape)
# 对输入进行零填充
padded_input = np.zeros((batch_size, input_channels, input_height + 2 * self.padding, input_width + 2 * self.padding))
padded_input[:, :, self.padding:input_height + self.padding, self.padding:input_width + self.padding] = input
# 卷积运算
for i in range(output_height):
for j in range(output_width):
for k in range(self.num_filters):
h_start = i * self.stride
h_end = h_start + self.filter_size
w_start = j * self.stride
w_end = w_start + self.filter_size
self.output[:, k, i, j] = np.sum(padded_input[:, :, h_start:h_end, w_start:w_end] * self.filters[k, :, :, :], axis=(1, 2, 3))
return self.output
def backward(self, output_error, learning_rate):
input_error = np.zeros(self.input_shape)
padded_input = np.zeros(self.input_shape)
padded_input[:, :, self.padding:self.input_shape[2] + self.padding, self.padding:self.input_shape[3] + self.padding] = self.input
filter_error = np.zeros(self.filters.shape)
for i in range(self.output_shape[2]):
for j in range(self.output_shape[3]):
for k in range(self.num_filters):
h_start = i * self.stride
h_end = h_start + self.filter_size
w_start = j * self.stride
w_end = w_start + self.filter_size
input_error[:, :, h_start:h_end, w_start:w_end] += self.filters[k, :, :, :] * output_error[:, k, i, j][:, None, None, None]
filter_error[k, :, :, :] += np.sum(padded_input[:, :, h_start:h_end, w_start:w_end] * output_error[:, k, i, j][:, None, None, None], axis=0)
# 更新参数
self.filters -= learning_rate * filter_error
return input_error
# 定义池化层
class MaxPoolingLayer:
def __init__(self, pool_size, stride):
self.pool_size = pool_size
self.stride = stride
def forward(self, input):
batch_size, num_channels, input_height, input_width = input.shape
output_height = int((input_height - self.pool_size) / self.stride + 1)
output_width = int((input_width - self.pool_size) / self.stride + 1)
self.output_shape = (batch_size, num_channels, output_height, output_width)
self.output = np.zeros(self.output_shape)
for i in range(output_height):
for j in range(output_width):
h_start = i * self.stride
h_end = h_start + self.pool_size
w_start = j * self.stride
w_end = w_start + self.pool_size
self.output[:, :, i, j] = np.max(input[:, :, h_start:h_end, w_start:w_end], axis=(2, 3))
return self.output
def backward(self, output_error):
input_error = np.zeros(self.output_shape)
for i in range(self.output_shape[2]):
for j in range(self.output_shape[3]):
for k in range(self.output_shape[1]):
h_start = i * self.stride
h_end = h_start + self.pool_size
w_start = j * self.stride
w_end = w_start + self.pool_size
max_pool = np.max(input[:, k, h_start:h_end, w_start:w_end], axis=(1, 2))
pool_mask = (input[:, k, h_start:h_end, w_start:w_end] == max_pool[:, None, None])
input_error[:, k, h_start:h_end, w_start:w_end] += output_error[:, k, i, j][:, None, None] * pool_mask
return input_error
```
以上是一个简单的CNN实现,包括卷积层和池化层,可以用于图像分类等任务。需要注意的是,这个实现只是为了展示CNN的基本原理,没有使用任何优化和加速技巧,性能可能不够好。如果需要在实际应用中使用CNN,建议使用现成的深度学习框架,如TensorFlow、PyTorch等。
阅读全文