def __call__(self, x): ''' Forward data through the network. This allows us to conveniently initialize a model `m` and then send data through it to be classified by calling `m(x)`. Parameters ---------- x : Union[numpy.ndarray, mygrad.Tensor], shape=(N, D) The data to forward through the network. Returns ------- mygrad.Tensor, shape=(N, 1) The model outputs. ''' # returns output of dense -> relu -> dense -> relu -> dense -> softmax three layer. temp1 = max_pool( self.conv2(relu(max_pool(self.conv1(x), pool=(2,2),stride=1))), pool=(2,2),stride=1) s = temp1.shape #print(temp1.shape) temp1 = temp1.reshape(s[0], s[1]*s[2]*s[3]) #print(temp1.shape) return self.dense3(relu(temp1))
def __call__(self, x): x = self.conv1(x) x = max_pool(x, (2, 2), 2) x = self.conv2(x) x = max_pool(x, (2, 2), 2) x = relu(self.dense1(x.reshape(x.shape[0], -1))) return self.dense2(x)
def test_maxpool(): # case 1 x = np.zeros((1, 1, 2, 2)) pool = 2 stride = 1 a = Tensor(x) f = max_pool(a, pool, stride) assert np.all(f.data == np.zeros((1, 1, 1, 1))) f.backward() assert np.all(a.grad == np.array([1, 0, 0, 0]).reshape(1, 1, 2, 2)) # case 2 x = np.arange(2 * 4 * 3).reshape(1, 2, 4, 3) x *= x[..., ::-1, ::-1] x[0, 0, 0, 1] = 400 out = np.array([[[[400, 400], [30, 28]], [[304, 306], [306, 304]]]]) pool = 2 stride = [2, 1] a = Tensor(x) f = max_pool(a, pool, stride) assert np.all(f.data == out) f.backward(np.arange(1, 9).reshape(1, 2, 2, 2)) da = np.array([[[[0, 3, 0], [0, 0, 0], [3, 4, 0], [0, 0, 0]], [[0, 0, 0], [0, 5, 6], [7, 8, 0], [0, 0, 0]]]]) assert np.all(da == a.grad)
def test_1d_case(): x = np.array([[[17, 10, 15, 28, 25, 23], [44, 26, 18, 16, 39, 34], [5, 42, 36, 0, 2, 46], [30, 20, 1, 31, 35, 43]], [[6, 7, 45, 27, 11, 8], [37, 4, 41, 22, 9, 33], [47, 3, 13, 32, 21, 38], [19, 12, 40, 24, 14, 29]]]) x = Tensor(x) pool = (3, ) stride = (1, ) out = max_pool(x, pool, stride) out.backward(np.arange(out.data.size).reshape(out.shape)) fwd_ans = np.array([[[17, 28, 28, 28], [44, 26, 39, 39], [42, 42, 36, 46], [30, 31, 35, 43]], [[45, 45, 45, 27], [41, 41, 41, 33], [47, 32, 32, 38], [40, 40, 40, 29]]]) bkc_ans = np.array([[[0., 0., 0., 6., 0., 0.], [4., 5., 0., 0., 13., 0.], [0., 17., 10., 0., 0., 11.], [12., 0., 0., 13., 14., 15.]], [[0., 0., 51., 19., 0., 0.], [0., 0., 63., 0., 0., 23.], [24., 0., 0., 51., 0., 27.], [0., 0., 87., 0., 0., 31.]]]) assert isinstance(out, Tensor) assert_allclose(fwd_ans, out.data) assert_allclose(bkc_ans, x.grad) assert max_pool(x, pool, stride, constant=True).constant is True assert max_pool(x, pool, stride, constant=False).constant is False
def __call__(self, x): ''' Forward data through the network. This allows us to conveniently initialize a model `m` and then send data through it to be classified by calling `m(x)`. Parameters ---------- x : Union[numpy.ndarray, mygrad.Tensor], shape=(N, D) The data to forward through the network. Returns ------- mygrad.Tensor, shape=(N, 1) The model outputs. ''' # STUDENT CODE # if num_filters = 10; (N, C, 32, 32) --> (N, 10, 28, 28) # if num_filters = 10; (N, C, 32, 32) --> (N, 10, 28, 28) x = self.conv1(x) # (N, 10, 28, 28) --> (N, 10, 14, 14) x = max_pool(x, (2,2), 2) # if num_filters = 20; (N, 10, 14, 14) --> (N, 20, 10, 10) x = self.conv2(x) # (N, 20, 10, 10) --> (N, 20, 5, 5) x = max_pool(x, (2,2), 2) # (N, 20, 5, 5) -reshape-> (N, 500) x (500, 20) -> (N, 20) x = relu(self.dense1(x.reshape(x.shape[0], -1))) # (N, 20) -> (N, 10) return self.dense2(x)
def __call__(self, x): x = relu(self.conv1(x)) x = max_pool(relu(self.conv2(x)), (2, 2), (2, 2)) x = relu(self.conv3(x)) x = max_pool(relu(self.conv4(x)), (2, 2), (2, 2)) x = x.reshape(x.shape[0], 256) x = relu(self.dense1(x)) x = self.dense2(x) return x
def text_constant(): x = np.array([[[17, 10, 15, 28, 25, 23], [44, 26, 18, 16, 39, 34], [5, 42, 36, 0, 2, 46], [30, 20, 1, 31, 35, 43]], [[6, 7, 45, 27, 11, 8], [37, 4, 41, 22, 9, 33], [47, 3, 13, 32, 21, 38], [19, 12, 40, 24, 14, 29]]]) x = Tensor(x) pool = (3, ) stride = (1, ) assert max_pool(x, pool, stride, constant=True).constant is True assert max_pool(x, pool, stride, constant=False).constant is False
def __call__(self, x): step1 = max_pool(relu(self.conv1(x)), (2, 2), stride=2) step2 = max_pool(relu(self.conv2(step1)), (2, 2), stride=2) flatten = step2.reshape(len(x), ) dense_layers = self.dense2(relu(self.dense1(flatten))) return dense_layers # returns output of dense -> relu -> dense -> relu -> dense -> softmax three layer. pass
def __call__(self, x): """ Forward data through the network. This allows us to conveniently initialize a model `m` and then send data through it to be classified by calling `m(x)`. Parameters ---------- x : Union[numpy.ndarray, mygrad.Tensor], shape=(N, D, S) The data to forward through the network. Returns ------- mygrad.Tensor, shape=(N, 1) The model outputs. Notes ----- N = batch size D = embedding size S = sentence length """ # <COGINST> # (N, D, S) with D = 200 and S = 77 x = self.conv1(x) # conv output shape (N, F, S') with F = 250 and S' = 75 x = relu(x) x = max_pool(x, (x.shape[-1],), 1) # global pool output shape (N, F, S') with F = 250, S' = 1 x = x.reshape(x.shape[0], -1) # (N, F, 1) -> (N, F) x = self.dense1(x) # (N, F) @ (F, D1) = (N, D1) x = relu(x) x = self.dense2(x) # (N, D1) @ (D1, 1) = (N, 1) x = sigmoid(x) return x # output shape (N, 1)
def __call__(self, x): ''' Defines a forward pass of the model. Parameters ---------- x : numpy.ndarray, shape=(N, 1, 28, 28) The input data, where N is the number of images. Returns ------- mygrad.Tensor, shape=(N, 10) The class scores for each of the N images. Pseudo-code ----------- >>> create dropout object >>> compute the first convolutional layer by doing x.conv1 >>> Perform ReLU by using relu(x) >>> Perform dropout by using x.dropout() >>> Use max_pool(x, size_pool, stride) to perform the pooling layer >>> repeat once >>> perform two dense layers with ReLU dropout in between ''' #first conv layer x = self.conv1(x) x = relu(x) x = self.dropout(x) x = max_pool(x, (2, 2), 2) #second conv layer x = self.conv2(x) x = relu(x) x = self.dropout(x) x = max_pool(x, (2, 2), 2) #performing the two dense layers x = x.reshape(x.shape[0], -1) x = self.dense1(x) x = relu(x) x = self.dropout(x) x = self.dense2(x) return x
def __call__(self, x): # convol1 = relu(self.conv1(x)) # pool1 = max_pool(convol1, pool=(2,2), stride=2) # convol2 = relu(self.conv2(pool1)) # pool2 = max_pool(convol2, pool=(2,2), stride=2) # flattened = pool2.reshape((len(x), 250)) # den3 = relu(self.dense3(flattened)) # den4 = self.dense4(den3) # return den4 #print(self.conv1(x).shape) step1 = max_pool(self.conv1(x), (2, 2), stride=2) step2 = max_pool(self.conv2(step1), (2, 2), stride=2) flatten = step2.reshape(-1, 500) dense_layers = self.dense2(relu(self.dense1(flatten))) return dense_layers # returns output of dense -> relu -> dense -> relu -> dense -> softmax three layer. pass
def test_bad_max_shapes(): x = Tensor(np.zeros((1, 2, 2, 2))) with raises(ValueError): max_pool(x, (3, ) * 3, (1, ) * 3) # large filter with raises(AssertionError): max_pool(x, (2, ) * 3, (0, ) * 3) # bad stride with raises(AssertionError): max_pool(x, (2, ) * 2, [1, 2, 3]) # bad stride with raises(ValueError): max_pool(x, (1, ) * 3, (3, ) * 3) # shape mismatch
def __call__(self, x): """ Performs a "forward-pass" of data through the network. This allows us to conveniently initialize a model `m` and then send data through it to be classified by calling `m(x)`. Parameters ---------- x : Union[numpy.ndarray, mygrad.Tensor], shape=(M, ?) A batch of data consisting of M pieces of data, each with a dimentionality of ? (the number of values among all the pixels in a given image). Returns ------- mygrad.Tensor, shape-(M, num_class) The model's prediction for each of the M images in the batch, """ x = relu(self.conv1(x)) x = max_pool(x, (2, 2), 2) x = relu(self.conv2(x)) x = max_pool(x, (2, 2), 2) x = relu(self.dense1(x.reshape(x.shape[0], -1))) return self.dense2(x)
def test_2d_case(): x = np.array([ [ [17, 10, 15, 28, 25, 23], [44, 26, 18, 16, 39, 34], [5, 42, 36, 0, 2, 46], [30, 20, 1, 31, 35, 43], ], [ [6, 7, 45, 27, 11, 8], [37, 4, 41, 22, 9, 33], [47, 3, 13, 32, 21, 38], [19, 12, 40, 24, 14, 29], ], ]) x = Tensor(x) pool = (2, 3) stride = (2, 1) out = max_pool(x, pool, stride) out.sum().backward() fwd_ans = np.array([[[44, 28, 39, 39], [42, 42, 36, 46]], [[45, 45, 45, 33], [47, 40, 40, 38]]]) bkc_ans = np.array([ [ [0.0, 0.0, 0.0, 1.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 2.0, 0.0], [0.0, 2.0, 1.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], ], [ [0.0, 0.0, 3.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 1.0], [1.0, 0.0, 0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 2.0, 0.0, 0.0, 0.0], ], ]) assert isinstance(out, Tensor) assert_allclose(fwd_ans, out.data) assert_allclose(bkc_ans, x.grad)
def test_3d_case(): x = np.array([ [ [33, 27, 47, 11, 7, 36], [20, 18, 9, 2, 3, 17], [45, 31, 24, 12, 25, 19], [28, 1, 8, 16, 34, 14], ], [ [37, 39, 40, 41, 21, 13], [35, 15, 6, 4, 23, 30], [43, 46, 32, 10, 26, 42], [38, 5, 44, 29, 0, 22], ], ]) x = Tensor(x) pool = (2, 2, 2) stride = (1, 1, 2) out = max_pool(x, pool, stride) g = np.arange(out.data.size) out.backward(g.reshape(out.shape)) fwd_ans = np.array([[[39, 47, 36], [46, 32, 42], [46, 44, 42]]]) bkc_ans = np.array([ [ [0.0, 0.0, 1.0, 0.0, 0.0, 2.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], ], [ [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 9.0, 4.0, 0.0, 0.0, 13.0], [0.0, 0.0, 7.0, 0.0, 0.0, 0.0], ], ]) assert isinstance(out, Tensor) assert_allclose(fwd_ans, out.data) assert_allclose(bkc_ans, x.grad)