コード例 #1
0
ファイル: ao_admm.py プロジェクト: nipsstickypgd/Sticky-GD
    def optimize(self, E, iterations):
        M = self.M
        W, H = utils.init_wh(M, self.k)
        V, U = utils.init_wh(M, self.k)

        for i in range(iterations):
            print(i, utils.objective(M, W, H, E))
            H, _ = admm_H_update(M, W, H, U, E, self.k)
            W, _ = admm_W_update(M, W, H, V, E, self.k)

        return W, H
コード例 #2
0
    def optimize(self, E, iterations):
        M = self.M
        W, H = utils.init_wh(M, self.k)
        for j in range(self.k):
            W[:, j] = W[:, j] / torch.norm(W[:, j])
            H[j, :] = H[j, :] / torch.norm(H[j, :])

        for i in range(iterations):
            print(i, utils.objective(M, W, H, E))
            Dif = E * (M - W.mm(H))
            for j in range(self.k):
                uj = W[:, j]
                vj = H[j, :]
                Dif = Dif + uj.reshape(-1, 1).mm(vj.reshape(1, -1))

                u_nom = Dif.t().mv(uj).clamp_min(0)
                if torch.norm(u_nom) > 1e-18:
                    vj = u_nom / (torch.norm(uj)**2)
                else:
                    vj = torch.zeros_like(vj)

                v_nom = Dif.mv(vj).clamp_min(0)
                if torch.norm(v_nom) > 1e-18:
                    uj = v_nom / (torch.norm(vj)**2)
                else:
                    uj = torch.zeros_like(uj)
                W[:, j] = uj
                H[j, :] = vj

                Dif = Dif - uj.reshape(-1, 1).mm(vj.reshape(1, -1))

        return W, H
コード例 #3
0
    def optimize(self, E, iterations):
        M = self.M
        W, H = utils.init_wh(M, self.k)
        for i in range(iterations):
            print(i, utils.objective(M, W, H, E))
            pH = H
            H = H + self.step * (W.T.mm(E * (M - W.mm(H))))
            H = utils.proj(H, pH, self.sticky)
            pW = W
            W = W + self.step * ((E * (M - W.mm(H))).mm(H.T))
            W = utils.proj(W, pW, self.sticky)

        return W, H
コード例 #4
0
    def optimize(self, E, iterations):
        M = self.M
        W, H = utils.init_wh(M, self.k)
        for i in range(iterations):
            print(i, utils.objective(M, W, H, E))
            # M_aux = (M - W.mm(H)) * E + W.mm(H)
            h_denom = W.t().mm(E * W.mm(H))
            H = H * torch.where(h_denom < 1e-10, eps, W.t().mm(M) / h_denom) # TODO
            # M_aux = (M - W.mm(H)) * E + W.mm(H)
            w_denom = (E * W.mm(H)).mm(H.t())
            W = W * torch.where(w_denom < 1e-10, eps, (M).mm(H.t()) / w_denom) # TODO

        return W, H
コード例 #5
0
ファイル: spgd.py プロジェクト: nipsstickypgd/Sticky-GD
    def optimize(self, E: Tensor, iterations):
        M = self.M
        W, H = utils.init_wh(M, self.k)
        mW, mH = 0, 0
        for i in range(iterations):
            print(i, utils.objective(M, W, H, E))
            prevW, prevH = W, H
            W = W + (1 - self.momentum) * mW
            H = H + (1 - self.momentum) * mH
            (gW, gH) = self.grad(M, W, H, E)
            # nW = np.random.normal(0, 0.01 * self.step, (n, self.k))
            # nH = np.random.normal(0, 0.01 * self.step, (self.k, m))
            W = utils.proj(W - self.step * gW, W, self.sticky)
            H = utils.proj(H - self.step * gH, H, self.sticky)
            mW = W - prevW
            mH = H - prevH

        return W, H
コード例 #6
0
    def optimize(self, iterations):
        M = self.M
        w, h = utils.init_wh(M, self.k)
        distance_type = self.distance_type
        w_aux = w.copy()
        h_aux = h.copy()

        # init dual variables for w, h, y
        dual_w = np.zeros_like(w)
        dual_h = np.zeros_like(h)
        v_aux = np.zeros_like(M)
        dual_v = np.zeros_like(M)

        reg_w = (0, 'nn')
        reg_h = (0, 'l2n')
        rho = 1

        for i in range(iterations):
            print(i, utils.objective(M, w, h))
            if distance_type == 'eu':
                h_aux = aux_update(h, dual_h, w_aux, M, None, rho,
                                   distance_type)
                w_aux = aux_update(w.T, dual_w.T, h_aux.T, M.T, None, rho,
                                   distance_type)
                w_aux = w_aux.T

                h = prox(reg_h[1], h_aux, dual_h, rho=rho, lambda_=reg_h[0])
                w = prox(reg_w[1],
                         w_aux.T,
                         dual_w.T,
                         rho=rho,
                         lambda_=reg_w[0])
                w = w.T

            elif distance_type == 'kl':
                h_aux = aux_update(h, dual_h, w_aux, v_aux, dual_v, rho,
                                   distance_type)
                w_aux = aux_update(w.T, dual_w.T, h_aux.T, v_aux.T, dual_v.T,
                                   rho, distance_type)
                w_aux = w_aux.T

                h = prox(reg_h[1], h_aux, dual_h, rho=rho, lambda_=reg_h[0])
                w = prox(reg_w[1],
                         w_aux.T,
                         dual_w.T,
                         rho=rho,
                         lambda_=reg_w[0])
                w = w.T

                v_bar = w_aux @ h_aux - dual_v
                v_aux = 1 / 2 * ((v_bar - 1) + np.sqrt((v_bar - 1)**2 + 4 * M))

                dual_v = dual_v + v_aux - w_aux @ h_aux

            else:
                raise TypeError('Unknown loss type.')

            dual_h = dual_h + h - h_aux
            dual_w = dual_w + w - w_aux

        return w, h