Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.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 韩元损失';暹罗网络上的t减少_Python_Opencv_Keras_Deep Learning_Neural Network - Fatal编程技术网

Python 韩元损失';暹罗网络上的t减少

Python 韩元损失';暹罗网络上的t减少,python,opencv,keras,deep-learning,neural-network,Python,Opencv,Keras,Deep Learning,Neural Network,我对机器学习非常陌生,我开始实施暹罗网络来检查手写数字的相似性水平,使用MNIST数据集进行训练,但我遇到了严重的丢失问题 网络模型 训练数据 我的pairs对象是一个带有两个数组的numpy数组,包含相同索引上的图像,数组的前半部分是相同类别的图像,后半部分是不同类别的图像 category对象是一个简单数组,包含来自训练集的相同数量的样本,它的前半部分为0,用于指定与同一图像相关的Y值,后半部分为1 对和类别都在以下函数中填充: INPUT_SHAPE = (28,28,1) def lo

我对机器学习非常陌生,我开始实施暹罗网络来检查手写数字的相似性水平,使用MNIST数据集进行训练,但我遇到了严重的丢失问题

网络模型 训练数据 我的
pairs
对象是一个带有两个数组的
numpy
数组,包含相同索引上的图像,数组的前半部分是相同类别的图像,后半部分是不同类别的图像

category
对象是一个简单数组,包含来自训练集的相同数量的样本,它的前半部分为
0
,用于指定与同一图像相关的Y值,后半部分为
1

类别
都在以下函数中填充:

INPUT_SHAPE = (28,28,1)

def loadData():
    (X_train, Y_train), _ = mnist.load_data()
    n_samples = 20000
    arrPairs = [np.zeros((n_samples, INPUT_SHAPE[0], INPUT_SHAPE[1],INPUT_SHAPE[2])) for i in range(2)]
    category = np.zeros((n_samples))
    category[n_samples//2:] = 1
    for i in range(n_samples): 
        if i%1000==0:
            print(i)

        cur_category = Y_train[i]

        img = random.choice(X_train[Y_train==cur_category]).reshape(28,28,1)
        _, img = cv2.threshold(img, .8, 1, cv2.THRESH_BINARY)
        arrPairs[0][i] = img.reshape(28,28,1)

        if category[i] == 1:
            img = random.choice(X_train[Y_train!=cur_category])
        else:
            img = random.choice(X_train[Y_train==cur_category])
        _, img = cv2.threshold(img, .8, 1, cv2.THRESH_BINARY)
        arrPairs[1][i] = img.reshape(28,28,1)
    arrPairs[0] = arrPairs[0]/255
    return arrPairs, category
培训结果 但无论我怎么做,损失都不会减少,因此,预测是错误的

我尝试过改变激活,增加和减少网络复杂性(添加和删除层,以及增加和减少
Conv2D
参数),但这些都不起作用,所以我猜这是我缺少的架构问题

更新: 用于测试的线路:

test_pairs = [np.zeros((2, INPUT_SHAPE[0], INPUT_SHAPE[1],INPUT_SHAPE[2])) for i in range(2)]
test_pairs[0][0] = cv2.cvtColor(cv2.imread('test1_samenumber.png'), cv2.COLOR_BGR2GRAY).reshape(28,28,1); 
test_pairs[1][0] = cv2.cvtColor(cv2.imread('test2_samenumber.png'), cv2.COLOR_BGR2GRAY).reshape(28,28,1);

pred = model.predict(test_pairs)
print(pred)
其中输出:

[[0.32230237]
 [0.44603676]]

在加载数据时,有不必要的规范化。具体地说,对于第一对图像,如果不是必需的话,可以将其除以255。使用
cv2.threshold
设置阈值后,输出值本质上是0或1,因此进一步除以255会使动态范围小于第二对图像,这可能会导致学习如何区分两个图像时出现问题。通过注释掉
arrPairs[0]=arrPairs[0]/255
语句,我删除了这种规范化

在我训练了你的网络之后,我浏览了每一对,并检查了输出预测。基本上,如果类别为1,并且网络(您的sigmoid层)生成的预测大于0.5,我将其视为正确的预测。类似地,当我看到类别为0且生成的预测小于0.5时,这也是正确的

correct = 0
for i in range(len(pairs[0])):
    output = model.predict([pairs[0][i][None], pairs[1][i][None]])[0][0]
    if (category[i] == 1 and output >= 0.5) or (category[i] == 0 and output < 0.5):
        correct += 1

print(correct / len(pairs[0]))
correct=0
对于范围内的i(len(对[0]):
输出=模型。预测([pairs[0][i][None],pairs[1][i][None]])[0][0]
如果(类别[i]==1,输出>=0.5)或(类别[i]==0,输出<0.5):
正确+=1
打印(正确/长度(对[0]))
我在这里得到了99.26%的准确率,这意味着20000个样本中有0.74%或大约148个样本被错误分类。我认为这是个好结果


可复制的谷歌Colab笔记本可以在这里找到:

谢谢你指出@rayryeng,我真的忘了。我应用了标准化,losst从0.60变为0.02。损失问题是由它引起的。但出于某种奇怪的原因,网络仍然错误地对图像进行分类,因为我拍摄了两张相同类别的图像,相同的概率为33%,而两张不同的图像相同的概率为99%,知道为什么吗?我查看了您数据中的唯一值。只有0和1,所以实际上我们需要删除规范化。这可能是因为您对数字设置了阈值,因此只有0和1的值。我有一个colab实例正在运行,在返回给您之前,我将对此进行测试。好的,我已经删除了不必要的规范化,看起来损失正在减少。我将等到它完成训练后再测试预测。我还冒昧地使您的代码具有可复制性。有一些函数调用和包丢失了,这将阻止任何人把它用完。谢谢你,确实丢失了。作为旁注,我试着手动写两个数字并进行比较,结果是不正确的,这意味着概括性没有那么好。有什么改进的建议吗?@RodolfoDonãHosp啊。有两种方法。(1) 在您的培训数据集中引入更多的缩放、旋转和平移,并在这些方面进行培训。希望有更多在比例、旋转和平移方面不同的例子,我们可以更好地概括。(2) 将您的文字图像引入数据集中。之所以如此糟糕,是因为您的文字与MNIST数据集有显著差异,尤其是在数字的比例和方向方面。取决于你认为什么更可行,我可以进一步建议你。@RodolfoDonãHosp。。。最重要的是,您必须对输入图像进行完全相同的预处理,就像在网络中进行推理之前使用MNIST一样。你在这么做吗?好的。这两个刻度可能不正确。请记住,MNIST数字占据整个图像。可能存在一些轻微的规模问题。尝试使用图像生成器并输入一些缩放、旋转和平移来概括模型。很高兴我能帮忙!如果您还需要什么,请告诉我。生成对时,它是一个包含两个元素的列表,其中列表中的每个元素都包含一个大小为
20000 x 28 x 28 x 1
的NumPy数组。2万份将是样品的总数。因此,您创建了一个包含两个元素的列表,每个元素的大小
1 x 28 x 28 x 1
,因此您可以表示一对图像以进行测试。您所要做的就是将
np.zero
声明的第一维度从2更改为1(即
[np.zero((1,INPUT_-SHAPE[0],INPUT_-SHAPE[1],INPUT_-SHAPE[2]),范围(2)]
中的i。这会产生两种概率,因为您为两个图像提供了第二个空白图像对。
[[0.32230237]
 [0.44603676]]
correct = 0
for i in range(len(pairs[0])):
    output = model.predict([pairs[0][i][None], pairs[1][i][None]])[0][0]
    if (category[i] == 1 and output >= 0.5) or (category[i] == 0 and output < 0.5):
        correct += 1

print(correct / len(pairs[0]))