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 112 113 114 115 116 117 118 119 120 121 122
| class ThreeLayerConvNet(object): """ A three-layer convolutional network with the following architecture:
conv - relu - 2x2 max pool - affine - relu - affine - softmax
The network operates on minibatches of data that have shape (N, C, H, W) consisting of N images, each with height H and width W and with C input channels. """
def __init__(self, input_dim=(3, 32, 32), num_filters=32, filter_size=7, hidden_dim=100, num_classes=10, weight_scale=1e-3, reg=0.0, dtype=np.float32): """ Initialize a new network.
Inputs: - input_dim: Tuple (C, H, W) giving size of input data - num_filters: Number of filters to use in the convolutional layer - filter_size: Size of filters to use in the convolutional layer - hidden_dim: Number of units to use in the fully-connected hidden layer - num_classes: Number of scores to produce from the final affine layer. - weight_scale: Scalar giving standard deviation for random initialization of weights. - reg: Scalar giving L2 regularization strength - dtype: numpy datatype to use for computation. """ self.params = {} self.reg = reg self.dtype = dtype
C, H, W = input_dim self.params['W1'] = weight_scale * np.random.randn(num_filters, C, filter_size, filter_size) self.params['b1'] = np.zeros(num_filters) self.params['W2'] = weight_scale * np.random.randn(int(H / 2) * int(W / 2)*num_filters, hidden_dim) self.params['b2'] = np.zeros(hidden_dim) self.params['W3'] = weight_scale * np.random.randn(hidden_dim, num_classes) self.params['b3'] = np.zeros(num_classes)
for k, v in self.params.items(): self.params[k] = v.astype(dtype)
def loss(self, X, y=None): """ Evaluate loss and gradient for the three-layer convolutional network.
Input / output: Same API as TwoLayerNet in fc_net.py. """ W1, b1 = self.params['W1'], self.params['b1'] W2, b2 = self.params['W2'], self.params['b2'] W3, b3 = self.params['W3'], self.params['b3']
filter_size = W1.shape[2] conv_param = {'stride': 1, 'pad': (filter_size - 1) // 2}
pool_param = {'pool_height': 2, 'pool_width': 2, 'stride': 2}
scores = None pass conv_forward_out_1, cache_forward_1 = conv_relu_pool_forward(X, W1, b1, conv_param, pool_param) affine_out_2, cache_forward_2 = affine_relu_forward(conv_forward_out_1, W2, b2) scores, cache_forward_3 = affine_forward(affine_out_2, W3, b3)
if y is None: return scores
loss, grads = 0, {} pass loss, dscore = softmax_loss(scores, y) da2, grads['W3'], grads['b3'] = affine_backward(dscore, cache_forward_3) da1, grads['W2'], grads['b2'] = affine_relu_backward(da2, cache_forward_2) _, grads['W1'], grads['b1'] = conv_relu_pool_backward(da1, cache_forward_1)
loss += 0.5 * self.reg * (np.sum(W1 ** 2) + np.sum(W2 **2) + np.sum(W3 ** 2))
grads['W1'] += self.reg * W1 grads['W2'] += self.reg * W2 grads['W3'] += self.reg * W3
return loss, grads
|