-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtwo_layers_cnn.py
More file actions
111 lines (92 loc) · 4.3 KB
/
Copy pathtwo_layers_cnn.py
File metadata and controls
111 lines (92 loc) · 4.3 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 16 18:57:17 2017
@author: Anthony
"""
import numpy as np
import cnn_numpy as layer
import cnn_numpy_utils as layer_util
def two_layer_convnet(X, model, y=None, reg=0.0):
"""
Compute the loss and gradient for a simple two-layer ConvNet. The architecture
is conv-relu-pool-affine-softmax, where the conv layer uses stride-1 "same"
convolutions to preserve the input size; the pool layer uses non-overlapping
2x2 pooling regions. We use L2 regularization on both the convolutional layer
weights and the affine layer weights.
Inputs:
- X: Input data, of shape (N, C, H, W)
- model: Dictionary mapping parameter names to parameters. A two-layer Convnet
expects the model to have the following parameters:
- W1, b1: Weights and biases for the convolutional layer
- W2, b2: Weights and biases for the affine layer
- y: Vector of labels of shape (N,). y[i] gives the label for the point X[i].
- reg: Regularization strength.
Returns:
If y is None, then returns:
- scores: Matrix of scores, where scores[i, c] is the classification score for
the ith input and class c.
If y is not None, then returns a tuple of:
- loss: Scalar value giving the loss.
- grads: Dictionary with the same keys as model, mapping parameter names to
their gradients.
"""
# Unpack weights
W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
N, C, H, W = X.shape
# We assume that the convolution is "same", so that the data has the same
# height and width after performing the convolution. We can then use the
# size of the filter to figure out the padding.
conv_filter_height, conv_filter_width = W1.shape[2:]
assert conv_filter_height == conv_filter_width, 'Conv filter must be square'
assert conv_filter_height % 2 == 1, 'Conv filter height must be odd'
assert conv_filter_width % 2 == 1, 'Conv filter width must be odd'
stride = 1
padding = (conv_filter_height - 1) / 2
pool_param = {'pool_height': 2, 'pool_width': 2, 'stride': 2}
# Compute the forward pass
a1, cache1 = layer_util.cnn_relu_pool_forward(X, W1, b1, stride, padding, pool_param)
scores, cache2 = layer.fully_connected_forward(a1, W2, b2)
if y is None:
return scores
# Compute the backward pass
data_loss, dscores = layer.softmax_loss(scores, y)
# Compute the gradients using a backward pass
da1, dW2, db2 = layer.fully_connected_backward(dscores, cache2)
dX, dW1, db1 = layer_util.cnn_relu_pool_backward(da1, cache1)
# Add regularization
dW1 += reg * W1
dW2 += reg * W2
reg_loss = 0.5 * reg * sum(np.sum(W * W) for W in [W1, W2])
loss = data_loss + reg_loss
grads = {'W1': dW1, 'b1': db1, 'W2': dW2, 'b2': db2}
return loss, grads
def init_two_layer_convnet(weight_scale=1e-3, bias_scale=0, input_shape=(3, 32, 32),
num_classes=10, num_filters=48, filter_size=5):
"""
Initialize the weights for a two-layer ConvNet.
Inputs:
- weight_scale: Scale at which weights are initialized. Default 1e-3.
- bias_scale: Scale at which biases are initialized. Default is 0.
- input_shape: Tuple giving the input shape to the network; default is
(3, 32, 32) for CIFAR-10.
- num_classes: The number of classes for this network. Default is 10
(for CIFAR-10)
- num_filters: The number of filters to use in the convolutional layer.
- filter_size: The width and height for convolutional filters. We assume that
all convolutions are "same", so we pick padding to ensure that data has the
same height and width after convolution. This means that the filter size
must be odd.
Returns:
A dictionary mapping parameter names to numpy arrays containing:
- W1, b1: Weights and biases for the convolutional layer
- W2, b2: Weights and biases for the fully-connected layer.
"""
B, R, C = input_shape
assert filter_size % 2 == 1, 'Filter size must be odd; got %d' % filter_size
model = {}
model['W1'] = weight_scale * np.random.randn(num_filters, B, filter_size, filter_size)
model['b1'] = bias_scale * np.random.randn(num_filters)
model['W2'] = weight_scale * np.random.randn(num_filters * R * C / 4, num_classes)
model['b2'] = bias_scale * np.random.randn(num_classes)
return model
pass