2

Я только начал изучать глубокое обучение. Я обнаружил, что застрял, когда дело дошло до градиентного спуска. Я знаю, как реализовать пакетный градиентный спуск. Я знаю, как это работает, а также то, как мини-пакетный и стохастический градиентный спуск работают теоретически. Но на самом деле не могу понять, как реализовать в коде.Как реализовать мини-пакетный спуск градиента в python?

import numpy as np 
X = np.array([ [0,0,1],[0,1,1],[1,0,1],[1,1,1] ]) 
y = np.array([[0,1,1,0]]).T 
alpha,hidden_dim = (0.5,4) 
synapse_0 = 2*np.random.random((3,hidden_dim)) - 1 
synapse_1 = 2*np.random.random((hidden_dim,1)) - 1 
for j in xrange(60000): 
    layer_1 = 1/(1+np.exp(-(np.dot(X,synapse_0)))) 
    layer_2 = 1/(1+np.exp(-(np.dot(layer_1,synapse_1)))) 
    layer_2_delta = (layer_2 - y)*(layer_2*(1-layer_2)) 
    layer_1_delta = layer_2_delta.dot(synapse_1.T) * (layer_1 * (1-layer_1)) 
    synapse_1 -= (alpha * layer_1.T.dot(layer_2_delta)) 
    synapse_0 -= (alpha * X.T.dot(layer_1_delta)) 

Это пример кода из блога ANDREW TRASK. Это мало и легко понять. Этот код реализует спуск градиента партии, но я хотел бы реализовать мини-пакетный и стохастический градиентный спуск в этом примере. Как я могу это сделать? Что мне нужно добавить/изменить в этом коде, чтобы реализовать мини-пакетный и стохастический градиентный спуск соответственно? Ваша помощь мне очень поможет. Заранее спасибо. (Я знаю, что в этом примере кода мало примеров, тогда как мне нужен большой набор данных для разбиения на мини-партии. Но я хотел бы знать, как его реализовать)

+0

Просто попробуйте мини-пакет внутри цикла for, таким образом измените имя исходного X на «wholeX» (и y также) и внутри цикла сделайте X, y = sample (wholeX, wholeY, size) », где образец будет ваша функция, возвращающая «размер» число случайных строк из целыхX, wholeY – lejlot

+0

Спасибо. Как вы сказали, моя функция вернет случайные строки, так что не возможно ли она возвращать одни и те же строки несколько раз? Это вызовет проблему? что если я поместил другой цикл for внутри цикла for и повторил его n раз. (n = мини-партии). Каждый раз, когда X, y будет отличаться. Хорошо ли, если это нормально, то как это на самом деле улучшает оптимизацию? – savan77

+0

случайная выборка без повторения является типичным решением, и ее нетрудно достичь, учитывая тот факт, что numpy.random имеет такой тип выборки. Другой для цикла является хорошим (хотя и не эффективным, поскольку петли питона медленны). оптимизация исходит из более математических причин, и здесь можно долго выражать свое мнение. Короче говоря, это дает вам много плохих оценок градиента при стоимости одного товара, что ускоряет оптимизацию – lejlot

ответ

6

Эта функция возвращает мини-партии входы и цели:

def iterate_minibatches(inputs, targets, batchsize, shuffle=False): 
    assert inputs.shape[0] == targets.shape[0] 
    if shuffle: 
     indices = np.arange(inputs.shape[0]) 
     np.random.shuffle(indices) 
    for start_idx in range(0, inputs.shape[0] - batchsize + 1, batchsize): 
     if shuffle: 
      excerpt = indices[start_idx:start_idx + batchsize] 
     else: 
      excerpt = slice(start_idx, start_idx + batchsize) 
     yield inputs[excerpt], targets[excerpt] 

и это говорит о том, как использовать его для обучения:

for n in xrange(n_epochs): 
    for batch in iterate_minibatches(X, Y, batch_size, shuffle=True): 
     x_batch, y_batch = batch 
     l_train, acc_train = f_train(x_batch, y_batch) 

    l_val, acc_val = f_val(Xt, Yt) 
    logging.info('epoch ' + str(n) + ' ,train_loss ' + str(l_train) + ' ,acc ' + str(acc_train) + ' ,val_loss ' + str(l_val) + ' ,acc ' + str(acc_val)) 

Очевидно, что вам нужно определить f_train, f_val и другие функции самостоятельно данную библиотеку оптимизации (например, лазанья , Keras), который вы используете.

+0

Спасибо .. я это понимаю. – savan77