Пример #1
0
    def test_FBPD_Norm1_cvx(self):
        if not cvx_not_installable:
            opt = {'memopt': True}
            # Problem data.
            m = 30
            n = 20
            np.random.seed(1)
            Amat = np.random.randn(m, n)
            A = LinearOperatorMatrix(Amat)
            bmat = np.random.randn(m)
            bmat.shape = (bmat.shape[0], 1)

            # A = Identity()
            # Change n to equal to m.

            b = DataContainer(bmat)

            # Regularization parameter
            lam = 10
            opt = {'memopt': True}
            # Create object instances with the test data A and b.
            f = Norm2sq(A, b, c=0.5, memopt=True)
            g0 = ZeroFun()

            # Initial guess
            x_init = DataContainer(np.zeros((n, 1)))

            # Create 1-norm object instance
            g1 = Norm1(lam)

            # Compare to CVXPY

            # Construct the problem.
            x1 = Variable(n)
            objective1 = Minimize(0.5 * sum_squares(Amat * x1 - bmat.T[0]) +
                                  lam * norm(x1, 1))
            prob1 = Problem(objective1)

            # The optimal objective is returned by prob.solve().
            result1 = prob1.solve(verbose=False, solver=SCS, eps=1e-9)

            # The optimal solution for x is stored in x.value and optimal objective value
            # is in result as well as in objective.value
            print(
                "CVXPY least squares plus 1-norm solution and objective value:"
            )
            print(x1.value)
            print(objective1.value)

            # Now try another algorithm FBPD for same problem:
            x_fbpd1, itfbpd1, timingfbpd1, criterfbpd1 = FBPD(
                x_init, Identity(), None, f, g1)
            print(x_fbpd1)
            print(criterfbpd1[-1])

            self.assertNumpyArrayAlmostEqual(numpy.squeeze(x_fbpd1.array),
                                             x1.value, 6)
        else:
            self.assertTrue(cvx_not_installable)
    # Construct the problem.
    x1 = Variable(n)
    objective1 = Minimize(0.5*sum_squares(Amat*x1 - bmat.T[0]) + lam*norm(x1,1) )
    prob1 = Problem(objective1)
    
    # The optimal objective is returned by prob.solve().
    result1 = prob1.solve(verbose=False,solver=SCS,eps=1e-9)
    
    # The optimal solution for x is stored in x.value and optimal objective value 
    # is in result as well as in objective.value
    print("CVXPY least squares plus 1-norm solution and objective value:")
    print(x1.value)
    print(objective1.value)
    
# Now try another algorithm FBPD for same problem:
x_fbpd1, itfbpd1, timingfbpd1, criterfbpd1 = FBPD(x_init,Identity(), None, f, g1)
print(x_fbpd1)
print(criterfbpd1[-1])

# Plot criterion curve to see both FISTA and FBPD converge to same value.
# Note that FISTA is very efficient for 1-norm minimization so it beats
# FBPD in this test by a lot. But FBPD can handle a larger class of problems 
# than FISTA can.
plt.figure()
plt.loglog(iternum[[0,-1]],[objective1.value, objective1.value], label='CVX LS+1')
plt.loglog(iternum,criter1,label='FISTA LS+1')
plt.legend()
plt.show()

plt.figure()
plt.loglog(iternum[[0,-1]],[objective1.value, objective1.value], label='CVX LS+1')
Пример #3
0
plt.imshow(x_fista1.array)
plt.title('FISTA Least squares plus 1-norm regularisation')
plt.show()

plt.semilogy(criter1)
plt.title('FISTA Least squares plus 1-norm regularisation criterion')
plt.show()

# The least squares plus 1-norm regularisation problem can also be solved by
# other algorithms such as the Forward Backward Primal Dual algorithm. This
# algorithm minimises the sum of three functions and the least squares and
# 1-norm functions should be given as the second and third function inputs.
# In this test case, this algorithm requires more iterations to converge, so
# new options are specified.
opt_FBPD = {'tol': 1e-4, 'iter': 20000}
x_fbpd1, it_fbpd1, timing_fbpd1, criter_fbpd1 = FBPD(x_init, None, f, g0,
                                                     opt_FBPD)

plt.imshow(x_fbpd1.array)
plt.title('FBPD for least squares plus 1-norm regularisation')
plt.show()

plt.semilogy(criter_fbpd1)
plt.title('FBPD for least squares plus 1-norm regularisation criterion')
plt.show()

# The FBPD algorithm can also be used conveniently for TV regularisation:

# Specify TV function object
lamtv = 10
gtv = TV2D(lamtv)
Пример #4
0
lam = 0.1
g0 = Norm1(lam)

# Run FISTA for least squares plus 1-norm function.
x_fista1, it1, timing1, criter1 = FISTA(x_init, f, g0, opt=opt)

plt.imshow(x_fista0.subset(horizontal_x=80).array)
plt.title('FISTA LS+1')
plt.colorbar()
plt.show()

# Run FBPD=Forward Backward Primal Dual method on least squares plus 1-norm
print("Run FBPD for least squares plus 1-norm regularisation")
x_fbpd1, it_fbpd1, timing_fbpd1, criter_fbpd1 = FBPD(x_init,
                                                     None,
                                                     f,
                                                     g0,
                                                     opt=opt)

plt.imshow(x_fbpd1.subset(horizontal_x=80).array)
plt.title('FBPD LS+1')
plt.colorbar()
plt.show()

# Run CGLS, which should agree with the FISTA least squares
print("Run CGLS for least squares")
x_CGLS, it_CGLS, timing_CGLS, criter_CGLS = CGLS(x_init,
                                                 Cop,
                                                 padded_data2,
                                                 opt=opt)
plt.imshow(x_CGLS.subset(horizontal_x=80).array)
Пример #5
0
    def test_FISTA_denoise_cvx(self):
        if not cvx_not_installable:
            opt = {'memopt': True}
            N = 64
            ig = ImageGeometry(voxel_num_x=N, voxel_num_y=N)
            Phantom = ImageData(geometry=ig)

            x = Phantom.as_array()

            x[int(round(N / 4)):int(round(3 * N / 4)),
              int(round(N / 4)):int(round(3 * N / 4))] = 0.5
            x[int(round(N / 8)):int(round(7 * N / 8)),
              int(round(3 * N / 8)):int(round(5 * N / 8))] = 1

            # Identity operator for denoising
            I = TomoIdentity(ig)

            # Data and add noise
            y = I.direct(Phantom)
            y.array = y.array + 0.1 * np.random.randn(N, N)

            # Data fidelity term
            f_denoise = Norm2sq(I, y, c=0.5, memopt=True)

            # 1-norm regulariser
            lam1_denoise = 1.0
            g1_denoise = Norm1(lam1_denoise)

            # Initial guess
            x_init_denoise = ImageData(np.zeros((N, N)))

            # Combine with least squares and solve using generic FISTA implementation
            x_fista1_denoise, it1_denoise, timing1_denoise, \
                criter1_denoise = \
                FISTA(x_init_denoise, f_denoise, g1_denoise, opt=opt)

            print(x_fista1_denoise)
            print(criter1_denoise[-1])

            # Now denoise LS + 1-norm with FBPD
            x_fbpd1_denoise, itfbpd1_denoise, timingfbpd1_denoise,\
                criterfbpd1_denoise = \
                FBPD(x_init_denoise, I, None, f_denoise, g1_denoise)
            print(x_fbpd1_denoise)
            print(criterfbpd1_denoise[-1])

            # Compare to CVXPY

            # Construct the problem.
            x1_denoise = Variable(N**2, 1)
            objective1_denoise = Minimize(
                0.5 * sum_squares(x1_denoise - y.array.flatten()) +
                lam1_denoise * norm(x1_denoise, 1))
            prob1_denoise = Problem(objective1_denoise)

            # The optimal objective is returned by prob.solve().
            result1_denoise = prob1_denoise.solve(verbose=False,
                                                  solver=SCS,
                                                  eps=1e-12)

            # The optimal solution for x is stored in x.value and optimal objective value
            # is in result as well as in objective.value
            print(
                "CVXPY least squares plus 1-norm solution and objective value:"
            )
            print(x1_denoise.value)
            print(objective1_denoise.value)
            self.assertNumpyArrayAlmostEqual(x_fista1_denoise.array.flatten(),
                                             x1_denoise.value, 5)

            self.assertNumpyArrayAlmostEqual(x_fbpd1_denoise.array.flatten(),
                                             x1_denoise.value, 5)
            x1_cvx = x1_denoise.value
            x1_cvx.shape = (N, N)

            # Now TV with FBPD
            lam_tv = 0.1
            gtv = TV2D(lam_tv)
            gtv(gtv.op.direct(x_init_denoise))

            opt_tv = {'tol': 1e-4, 'iter': 10000}

            x_fbpdtv_denoise, itfbpdtv_denoise, timingfbpdtv_denoise,\
                criterfbpdtv_denoise = \
                FBPD(x_init_denoise, gtv.op, None, f_denoise, gtv, opt=opt_tv)
            print(x_fbpdtv_denoise)
            print(criterfbpdtv_denoise[-1])

            # Compare to CVXPY

            # Construct the problem.
            xtv_denoise = Variable((N, N))
            objectivetv_denoise = Minimize(0.5 *
                                           sum_squares(xtv_denoise - y.array) +
                                           lam_tv * tv(xtv_denoise))
            probtv_denoise = Problem(objectivetv_denoise)

            # The optimal objective is returned by prob.solve().
            resulttv_denoise = probtv_denoise.solve(verbose=False,
                                                    solver=SCS,
                                                    eps=1e-12)

            # The optimal solution for x is stored in x.value and optimal objective value
            # is in result as well as in objective.value
            print(
                "CVXPY least squares plus 1-norm solution and objective value:"
            )
            print(xtv_denoise.value)
            print(objectivetv_denoise.value)

            self.assertNumpyArrayAlmostEqual(x_fbpdtv_denoise.as_array(),
                                             xtv_denoise.value, 1)

        else:
            self.assertTrue(cvx_not_installable)
Пример #6
0
g1 = Norm1(lam)

g1(x_init)
g1.prox(x_init, 0.02)

# Combine with least squares and solve using generic FISTA implementation
x_fista1, it1, timing1, criter1 = FISTA(x_init, f, g1)
x_fista1_m, it1_m, timing1_m, criter1_m = FISTA(x_init, f, g1, opt=opt)
iternum = [i for i in range(len(criter1))]
# Print for comparison
print("FISTA least squares plus 1-norm solution and objective value:")
print(x_fista1)
print(criter1[-1])

# Now try another algorithm FBPD for same problem:
x_fbpd1, itfbpd1, timingfbpd1, criterfbpd1 = FBPD(x_init, None, f, g1)
iternum = [i for i in range(len(criterfbpd1))]
print(x_fbpd1)
print(criterfbpd1[-1])

# Plot criterion curve to see both FISTA and FBPD converge to same value.
# Note that FISTA is very efficient for 1-norm minimization so it beats
# FBPD in this test by a lot. But FBPD can handle a larger class of problems
# than FISTA can.
plt.figure()
plt.loglog(iternum, criter1, label='FISTA LS+1')
plt.loglog(iternum, criter1_m, label='FISTA LS+1 memopt')
plt.legend()
plt.show()

plt.figure()
Пример #7
0
#%%

#%% Then run FBPD algorithm for TV  denoising

# Initial guess
x_init_denoise = ImageData(np.zeros((N, N)))

# Set up TV function
gtv = TV2D(lam_tv)

# Evalutate TV of noisy image.
gtv(gtv.op.direct(y))

# Specify FBPD options and run FBPD.
opt_tv = {'tol': 1e-4, 'iter': 10000}
x_fbpdtv_denoise, itfbpdtv_denoise, timingfbpdtv_denoise, criterfbpdtv_denoise = FBPD(
    x_init_denoise, None, f_denoise, gtv, opt=opt_tv)

print("FBPD least squares plus TV solution and objective value:")
plt.figure()
plt.imshow(x_fbpdtv_denoise.as_array())
plt.title('FBPD TV with objective equal to {:.2f}'.format(
    criterfbpdtv_denoise[-1]))
plt.show()

print(criterfbpdtv_denoise[-1])

# Also plot history of criterion vs. CVX
if use_cvxpy:
    plt.loglog([0, opt_tv['iter']],
               [objectivetv_denoise.value, objectivetv_denoise.value],
               label='CVX TV')
Пример #8
0
plt.title('FISTA Least squares plus 1-norm regularisation')
plt.show()

plt.semilogy(criter1)
plt.title('FISTA Least squares plus 1-norm regularisation criterion')
plt.show()

# The least squares plus 1-norm regularisation problem can also be solved by
# other algorithms such as the Forward Backward Primal Dual algorithm. This
# algorithm minimises the sum of three functions and the least squares and
# 1-norm functions should be given as the second and third function inputs.
# In this test case, this algorithm requires more iterations to converge, so
# new options are specified.
x_fbpd1, it_fbpd1, timing_fbpd1, criter_fbpd1 = FBPD(x_init,
                                                     None,
                                                     f,
                                                     g0,
                                                     opt=opt)

plt.imshow(x_fbpd1.subset(vertical=0).array)
plt.title('FBPD for least squares plus 1-norm regularisation')
plt.show()

plt.semilogy(criter_fbpd1)
plt.title('FBPD for least squares plus 1-norm regularisation criterion')
plt.show()

# Compare all reconstruction and criteria

clims = (0, 1)
cols = 3