I'm implementing a CNN with Numpy and Scipy to solidify my understanding, but I'm encountering a rather strange problem.My layers are: input -> conv -> pool -> FCHere are the relevant functions:def unpackTheta (theta, filterSize, numFilters, pooledDim, outputSize):    a = filterSize ** 2 * numFilters    b = a + numFilters    c = b + pooledDim ** 2 * numFilters * outputSize    d = c + outputSize    return (np.reshape(theta[0 : a], (filterSize, filterSize, numFilters)),            np.reshape(theta[a : b], (numFilters)),            np.reshape(theta[b : c], (pooledDim ** 2 * numFilters, outputSize)),            np.reshape(theta[c : d], (outputSize)))def getConvolution (features, Wc, Bc, numFilters, numImages, filteredSize):    conv = np.zeros((filteredSize, filteredSize, numFilters, numImages))    for imageNum in range(numImages):        image = features[:, :, imageNum]        for filterNum in range(numFilters):            filterLayer = np.rot90(Wc[:, :, filterNum], 2)            conv[:, :, filterNum, imageNum] = sigmoid(convolve2d(image, filterLayer, 'valid') + Bc[filterNum])    return convdef getPooled (features, poolSize, pooledSize, filteredSize, numFilters, numImages):    ret = np.empty((pooledSize, pooledSize, numFilters, numImages))    poolFilter = np.ones((poolSize, poolSize)) / poolSize ** 2    for i in range(numFilters):         for j in range(numImages):            pooledLayer = convolve2d(features[:, :, i, j], poolFilter, 'valid')            for x in range(0, filteredSize, poolSize):                for y in range(0, filteredSize, poolSize):                    ret[x / poolSize, y / poolSize, i, j] = pooledLayer[x, y]    return retdef getCost (theta, *args) :    ## Initializing variables    features, inputSize, filterSize, numFilters, poolSize, outputSize, reg = args    filteredSize = inputSize - filterSize + 1    pooledSize = filteredSize / poolSize    (Wc, Bc, Wr, Br) = unpackTheta(theta, filterSize, numFilters, pooledSize, outputSize)    numImages = np.size(features, 0)    actualValues = np.eye(outputSize)[features[:, 0]]    features = np.reshape(features[:, 1:] / 255.0, (inputSize, inputSize, numImages))    ## Forward propagation    # Convolution    conv = getConvolution(features, Wc, Bc, numFilters, numImages, filteredSize)    # Mean pooling    pooled = np.reshape(getPooled(conv, poolSize, pooledSize, filteredSize, numFilters, numImages), (-1, numImages))    # Logistic regression    calcValues = sigmoid(pooled.transpose().dot(Wr) + Br)    ## Calculating cost    cost = -np.sum(actualValues * np.log(calcValues) + (1 - actualValues) * np.log(1 - calcValues)) / numImages    cost += reg * (np.sum(Wc ** 2) + np.sum(Wr ** 2)) / (2 * numImages)    ## Back propagation    #print Wr    #print Br    outputError = (calcValues - actualValues)     pooledError = Wr.dot(outputError.transpose())    pooledError = np.reshape(pooledError, (pooledSize, pooledSize, numFilters, numImages))    convError = np.empty((filteredSize, filteredSize, numFilters, numImages))    convErrorFilter = np.ones((poolSize, poolSize)) / (poolSize ** 2)    for i in range(numFilters):        for j in range(numImages):            convError[:, :, i, j] = np.kron(pooledError[:, :, i, j], convErrorFilter)    convError *= conv * (1 - conv)    ## Gradient    WrGrad = pooled.dot(outputError)    BrGrad = np.sum(outputError, 0)    WcGrad = np.zeros((filterSize, filterSize, numFilters))    BcGrad = np.empty(numFilters)    for i in range(numFilters):        BcGrad[i] = np.sum(convError[:, :, i, :])        for j in range(numImages):             filterLayer = np.rot90(convError[:, :, i, j], 2)            WcGrad[:, :, i] += convolve2d(features[:, :, j], filterLayer, 'valid')    WrGrad /= numImages    WcGrad /= numImages    BrGrad /= numImages    BcGrad /= numImages    WrGrad += reg * Wr / numImages    WcGrad += reg * Wc / numImages    global costCache    costCache = cost    return (cost, np.concatenate((WcGrad.flatten(), BcGrad.flatten(), WrGrad.flatten(), BrGrad.flatten()), axis=0))I implemented a numerical gradient to verify if it was returning the right values, and it was. However, my softmax regression seems to be predicting the same value across the entire batch when I do SGD.However, when I use scipy.minimize function, it gives me different values for softmax regressionAny help is greatly appreciated.
Error with Convolutional Neural Network (SGD?)
machine learning;neural network