Почему производные установлены на ноль для LSTM - PullRequest
1 голос
/ 28 января 2020

Я просматриваю этот код ниже:


class LstmParam:
    def __init__(self, mem_cell_ct, x_dim):
        self.mem_cell_ct = mem_cell_ct
        self.x_dim = x_dim
        concat_len = x_dim + mem_cell_ct
        # weight matrices
        self.wg = rand_arr(-0.1, 0.1, mem_cell_ct, concat_len)
        self.wi = rand_arr(-0.1, 0.1, mem_cell_ct, concat_len) 
        self.wf = rand_arr(-0.1, 0.1, mem_cell_ct, concat_len)
        self.wo = rand_arr(-0.1, 0.1, mem_cell_ct, concat_len)
        # bias terms
        self.bg = rand_arr(-0.1, 0.1, mem_cell_ct) 
        self.bi = rand_arr(-0.1, 0.1, mem_cell_ct) 
        self.bf = rand_arr(-0.1, 0.1, mem_cell_ct) 
        self.bo = rand_arr(-0.1, 0.1, mem_cell_ct) 
        # diffs (derivative of loss function w.r.t. all parameters)
        self.wg_diff = np.zeros((mem_cell_ct, concat_len)) 
        self.wi_diff = np.zeros((mem_cell_ct, concat_len)) 
        self.wf_diff = np.zeros((mem_cell_ct, concat_len)) 
        self.wo_diff = np.zeros((mem_cell_ct, concat_len)) 
        self.bg_diff = np.zeros(mem_cell_ct) 
        self.bi_diff = np.zeros(mem_cell_ct) 
        self.bf_diff = np.zeros(mem_cell_ct) 
        self.bo_diff = np.zeros(mem_cell_ct) 

    def apply_diff(self, lr = 1):
        self.wg -= lr * self.wg_diff
        self.wi -= lr * self.wi_diff
        self.wf -= lr * self.wf_diff
        self.wo -= lr * self.wo_diff
        self.bg -= lr * self.bg_diff
        self.bi -= lr * self.bi_diff
        self.bf -= lr * self.bf_diff
        self.bo -= lr * self.bo_diff
        # reset diffs to zero
        self.wg_diff = np.zeros_like(self.wg)
        self.wi_diff = np.zeros_like(self.wi) 
        self.wf_diff = np.zeros_like(self.wf) 
        self.wo_diff = np.zeros_like(self.wo) 
        self.bg_diff = np.zeros_like(self.bg)
        self.bi_diff = np.zeros_like(self.bi) 
        self.bf_diff = np.zeros_like(self.bf) 
        self.bo_diff = np.zeros_like(self.bo) 

Я не понимаю, почему это применяется производный так рано для self.wg_diff = np.zeros((mem_cell_ct, concat_len)). Я не уверен, что здесь происходит. Я также смущен, почему они установлены в ноль. Если кто-то может объяснить, почему это будет оценено.

1 Ответ

1 голос
/ 28 января 2020

Строка, такая как

self.wg_diff = np.zeros((mem_cell_ct, concat_len)) 

, не , применяющая производную, она просто инициализирует массив, который позже будет содержать производные функции потерь по значениям в wg массив.

В apply_diff здесь применяется градиент:

self.wg -= lr * self.wg_diff

Важно: между вызовом функции __init__ для создания экземпляр LstmParam и вызов apply_diff для применения градиентов, другой код (который вы не показываете) должен изменить self.wg_diff так, чтобы он действительно содержал производные.

Для вычисления градиентов,

  • Для прямого прохода необходимо использовать некоторые данные в качестве входных данных и вычислить выходной сигнал, в котором для вычисления используются значения в wg.
  • Затем выходной сигнал сравнивается с требуемым правильным выходным значением с функция потерь.
  • После вычисления потерь обратный проход вычисляет градиенты (производные функции потерь по всем весам, которые участвуют в вычислении выходных данных). Обратный проход заполняет self.wg_diff фактическими значениями.

Для полноты следующая строка

self.wg_diff = np.zeros_like(self.wg)

сбрасывает массив градиентов для следующего обратного прохода.

...