Beispiel #1
0
    def update(self, learning_rate):
        #반복문 개선 버전 (최적화)
        def update_(x, delta_x):
            return x - learning_rate.array[0] * delta_x  #learning_rate는 캡쳐됨.

        tensor.function_elment_wise(self.gamma, self.dgamma, update_,
                                    self.gamma)
        tensor.function_elment_wise(self.beta, self.dbeta, update_, self.beta)
Beispiel #2
0
 def accuracy(self, table):
     """forward를 반드시 해야 하고, backward 이전에 사용해야 합니다."""
     out = self.layers[-1].out
     out_argmax = tensor.argmax(out, -1, tensor.create_sum(out, -1))
     table_argmax = tensor.argmax(table, -1, tensor.create_sum(table, -1))
     eq = tensor.function_elment_wise(
         out_argmax, table_argmax, Layers._equal,
         tensor.create_element_wise_product(out_argmax, table_argmax, int))
     reduce_sum = tensor.sum_axis(eq, 0, tensor.Tensor([1], [1]))
     return reduce_sum.array[0] / len(out_argmax.array)
Beispiel #3
0
    def backward(self, dout):
        #반복문 최소화하기 위한 함수
        def comput_new_dxc(dxc, xc_dvar):
            return dxc + (2.0 / self.batch_size) * xc_dvar

        def comput_dx(dxc, dmu):
            return dxc - dmu / self.batch_size

        tensor.mul(self.gamma, dout,
                   self.out)  # out를 dxn으로 사용(기존 forward out 손실)
        tensor.mul(self.out, self.xc, self.tmp_out_shape)  #dstd를 구하기 전단계
        #반복문 최소화 기능.
        tensor.function_elment_wise(
            self.tmp_out_shape, self.std, BatchNormalization.comput_dstd,
            self.tmp_out_shape)  #tmp_out_shape은 dstd(np.sum하기 전)로 사용
        tensor.function_elment_wise(
            self.tmp_out_shape, self.std, BatchNormalization.comput_dvar,
            self.tmp_out_shape)  #tmp_out_shape는 dvar(np.sum하기 전)로 사용
        tensor.sum_axis(self.tmp_out_shape, 0,
                        self.dbeta)  #self.dbeta는 dvar로 사용(기존 dbeta값 손실)

        tensor.mul(self.xc, self.dbeta,
                   self.xc)  #xc를 xc와 dvar의 곱으로 사용(기존 xc값 손실) (dvar의 역할 끝)

        tensor.div(self.out, self.std,
                   self.out)  # out을 dxc로 사용 (dxn값 손실) (dxn 역할 끝)
        tensor.function_elment_wise(self.out, self.xc, comput_new_dxc,
                                    self.out)

        tensor.sum_axis(self.out, 0, self.dbeta)  #dmu를 dbeta로 사용(기존 dvar값 손실)
        tensor.function_elment_wise(self.out, self.dbeta, comput_dx,
                                    self.out)  #최종 backward값(dxn값 손실)

        tensor.sum_axis(dout, 0, self.dbeta)
        tensor.mul(
            self.xn, dout, self.tmp_out_shape
        )  #tmp_out_shape는 dgamma를 구하기 위한 임시 객체로 재활용 (기존 dvar(np.sum하기 전)값 손실)
        tensor.sum_axis(self.tmp_out_shape, 0, self.dgamma)

        return self.out
Beispiel #4
0
    def forward(self, x):
        #최적화 기법
        def multiply_momentum_and_add(left, right):
            return left * self.momentum + (1 -
                                           self.momentum) * right  #momentum 캡쳐

        if (self.out.shape[0] != x.shape[0]):
            self.xc = x.copy()
            self.xn = x.copy()
            self.out = x.copy()
            self.tmp_out_shape = x.copy()
            self.batch_size = x.shape[0]

        if self.running_mean is None:
            D = len(x.array) // x.shape[0]
            self.running_mean = tensor.create_zeros([D])
            self.running_var = tensor.create_zeros([D])
            self.std = self.running_mean.copy()
            #self.tmp_sum_axis = self.running_mean.copy()
            self.dbeta = self.running_mean.copy()
            self.dgamma = self.running_mean.copy()

        if self.train_flg:
            #tmp_sum_axis가 나중에 추가되서 값이 이상하게 나오면 바꾸자.
            tensor.mean_axis(x, 0, self.std)  #std가 임시 객체로 활용. (mu에 해당)
            #self.running_mean = self.momentum * self.running_mean + (1-self.momentum) * mu #(넘파이 버전)
            tensor.function_elment_wise(self.running_mean, self.std,
                                        multiply_momentum_and_add,
                                        self.running_mean)
            tensor.sub(x, self.std, self.xc)
            tensor.function(self.xc, BatchNormalization.jegop,
                            self.xn)  #xn도 계산에 필요한 임시 객체로 사용
            tensor.mean_axis(self.xn, 0, self.std)  #std가 임시 객체로 활용(var에 해당)
            #self.running_var = self.momentum * self.running_var + (1-self.momentum) * var #넘파이 버전 알고리즘
            tensor.function_elment_wise(self.running_var, self.std,
                                        multiply_momentum_and_add,
                                        self.running_var)
            tensor.function(self.std, BatchNormalization.sqrt,
                            self.std)  # std가 가져야 할 값
            tensor.div(self.xc, self.std, self.xn)  #xn이 가져야 할 값
        else:
            tensor.sub(x, self.running_mean, self.xc)
            tensor.function_elment_wise(self.xc, self.running_var,
                                        BatchNormalization.sqrt_and_div,
                                        self.xn)
        tensor.mul(self.gamma, self.xn, self.out)
        tensor.add(self.out, self.beta, self.out)
        return self.out
Beispiel #5
0
    def update(self, learning_rate):
        def update_(x, delta_x):
            return x - learning_rate.array[0] * delta_x  #learning_rate는 캡쳐됨.

        tensor.function_elment_wise(self.W, self.dW, update_, self.W)
        tensor.function_elment_wise(self.b, self.db, update_, self.b)
Beispiel #6
0
 def backward(self, dout):
     tensor.function_elment_wise(dout, self.out, Relu.relu_dfunc,
                                 self.out)  # 기존 out값이 손실 됨.
     return self.out