Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多元优化-scipy.optimize输入解析错误_Python_Image_Numpy_Math_Least Squares - Fatal编程技术网

Python 多元优化-scipy.optimize输入解析错误

Python 多元优化-scipy.optimize输入解析错误,python,image,numpy,math,least-squares,Python,Image,Numpy,Math,Least Squares,我将上面的rgb图像保存为tux.jpg。现在我想得到这个图像最接近的近似值,它是两个向量的外积,即A·BT形式 这是我的密码- #load image to memory import Image im = Image.open('tux.jpg','r') #save image to numpy array import numpy as np mat = np.asfarray(im.convert(mode='L')) # mat is a numpy array of dimensi

我将上面的rgb图像保存为
tux.jpg
。现在我想得到这个图像最接近的近似值,它是两个向量的外积,即A·BT形式

这是我的密码-

#load image to memory
import Image
im = Image.open('tux.jpg','r')
#save image to numpy array
import numpy as np
mat = np.asfarray(im.convert(mode='L')) # mat is a numpy array of dimension 354*300
msizex,msizey = mat.shape
x0 = np.sum(mat,axis=1)/msizex
y0 = np.sum(mat,axis=0)/msizey

X0 = np.concatenate((x0,y0)) # X0.shape is (654,)
# define error of outer product with respect to original image
def sumsquares(X):
    """ sum of squares - 
    calculates the difference between original and outer product

    input X is a 1D numpy array with the first 354 elements
    representing vector A and the rest 300 representing vector B.
    The error is obtained by subtracting the trial  $A\cdot B^T$ 
    from the original and then adding the square of all entries in 
    the matrix.
    """
    assert X.shape[0] == msizex+msizey
    x = X0[:msizex]
    y = X0[msizex:]
    return np.sum(
        (
        np.outer(x,y) - mat
        )**2
    )
#import minimize
from scipy.optimize import minimize
res = minimize(sumsquares, X0,
               method='nelder-mead',
               options={'disp':True}
)
xout = res.x[:msizex]
yout = res.x[msizex:]
mout = np.outer(xout,yout)
imout= Image.fromarray(mout,mode='L')
imout.show()
结果是

我觉得这个不够好。有什么办法可以改进这一点吗?输出中的噪声甚至与原始图片中的结构长度不同。我的猜测是算法没有通过。如何调试或改进此功能

编辑1:我用代码创建了下面的图像

size = 256
mat0 = np.zeros((size,size))
mat0[size/4:3*size/4,size/4:3*size/4] = 1000
#mat0[size/4:3*size/4,] = 1000
#mat0[:3*size/4,size/4:] = 1000

im0 = Image.fromarray(mat0)
im0.show() 
注释掉的两行将生成另外两个图像。这是我的实验结果-

在正方形中间。 输入-
输出-相同 在中间带。 输入-
输出-
  • 东北部的白色区块 输入-
    输出-
  • 虽然这比我预期的要好得多,但案例2和案例3最终仍然是错误的。我希望
    minimize
    函数的参数是我认为它们的意思

    1)在从numpy数组到图像的转换过程中,第一个图像的渲染问题似乎是一个问题。我通过运行以下命令获得正确的渲染:

    imout = Image.fromarray(mout/np.max(mout)*255)
    
    (即,将图像规格化为最大值255,并让其自动确定模式)

    通常,要检查Image.fromarray是否正常工作,比较imout.show()的输出与

    你应该得到同样的结果。顺便说一句,通过这样做,我得到了所有其他3个案例的正确答案

    2) 其次,tux.png的主要问题是,仅用两个一维向量的外积无法重建具有如此详细结构的图像

    (这通常适用于简单的图像,如上面所示的块状图像,但不适用于对称性少、细节多的图像)

    为了证明这一点:

    • 存在允许将矩阵重构为两个低秩矩阵M=AB的乘积的矩阵分解技术,例如

    • 在这种情况下,将A和B的秩设置为1相当于您的问题(使用不同的优化技术)

    • 使用下面的代码,您可以很容易地看到,如果n_分量=1(相当于两个1-D向量的外积),生成的重构矩阵看起来与方法输出的矩阵非常相似,并且n_分量越大,重构效果越好

    对于再现性:

    import matplotlib.pyplot as plt
    from sklearn.decomposition import NMF
    
    nmf = NMF(n_components=20)
    prj = nmf.fit_transform(mat)
    
    out = prj.dot(nmf.components_)
    out = np.asarray(out, dtype=float)
    
    imout = Image.fromarray(out)
    imout.show()
    
    为了便于说明,这是一个分量的NMF重建(这正是两个一维向量之间的外积):

    由两部分组成:

    这是由20个部件组成的NMF重建

    这清楚地表明,一个单一的1-D外部产品是不够的图像。但是,它适用于块状图像

    如果你不局限于向量的外积,那么矩阵分解可以是一种替代方法。顺便说一句,存在大量的矩阵分解技术。sklearn中的另一个选择是

    3) 最后,x0和y0中可能存在缩放问题。注意,np.outer(x0,y0)的元素比mat的元素高几个数量级

    虽然我仍然使用提供的代码对3个块状示例获得了很好的结果,但一般来说,在计算平方差时使用可比较的尺度是一个很好的实践。例如,您可能希望缩放x0和y0,以便np.outer的范数与mat的范数相当

    1)在从numpy数组到图像的转换过程中,第一个图像的渲染问题似乎是一个问题。我通过运行以下命令获得正确的渲染:

    imout = Image.fromarray(mout/np.max(mout)*255)
    
    (即,将图像规格化为最大值255,并让其自动确定模式)

    通常,要检查Image.fromarray是否正常工作,比较imout.show()的输出与

    你应该得到同样的结果。顺便说一句,通过这样做,我得到了所有其他3个案例的正确答案

    2) 其次,tux.png的主要问题是,仅用两个一维向量的外积无法重建具有如此详细结构的图像

    (这通常适用于简单的图像,如上面所示的块状图像,但不适用于对称性少、细节多的图像)

    为了证明这一点:

    • 存在允许将矩阵重构为两个低秩矩阵M=AB的乘积的矩阵分解技术,例如

    • 在这种情况下,将A和B的秩设置为1相当于您的问题(使用不同的优化技术)

    • 使用下面的代码,您可以很容易地看到,如果n_分量=1(相当于两个1-D向量的外积),生成的重构矩阵看起来与方法输出的矩阵非常相似,并且n_分量越大,重构效果越好

    对于再现性:

    import matplotlib.pyplot as plt
    from sklearn.decomposition import NMF
    
    nmf = NMF(n_components=20)
    prj = nmf.fit_transform(mat)
    
    out = prj.dot(nmf.components_)
    out = np.asarray(out, dtype=float)
    
    imout = Image.fromarray(out)
    imout.show()
    
    为了便于说明,这是一个分量的NMF重建(这正是两个一维向量之间的外积):

    由两部分组成:

    这是由20个部件组成的NMF重建

    这清楚地表明,一个单一的1-D外部产品是不够的图像。但是,它适用于块状图像

    如果你不局限于向量的外积,那么矩阵分解可以是一种替代方法。顺便说一句,存在大量的矩阵分解技术。sklearn中的另一个选择是

    3) 最后,x0和y0中可能存在缩放问题。注意,np.outer(x0,y0)的元素比mat的元素高几个数量级

    虽然我仍然得到了3块示例的好结果