我問了一個關於我一直在建設的網絡的問題last week,,我重複了那些讓我發現幾個問題的建議。我已經回到這個項目,並解決了所有問題,並在此過程中瞭解了更多關於CNN的很多。現在我遇到了一個問題,就是我的所有權重都轉移到了大量的負值,這與RELU在輸出圖像中總是以完全黑色結束(使分類器無法完成它的工作)相關。卷積網絡過濾器總是負面的
在2個標記圖像:
這些被傳遞到兩個層網絡,一個分類器(其自身得到100%)和一個過濾器3×3的卷積層。
在第一次迭代來自卷積層的輸出如下所示(以與上述順序相同的圖像):
該過濾器是3 * 3 * 3中,由於圖像是RGB。權重都是0.0f-1.0f之間的隨機數。在下一次迭代中,圖像完全是黑色,打印過濾器顯示它們現在處於-49678.5f(我能看到的最高)和-61932.3f的範圍內。
這個問題反過來是由於交叉(標籤0,預測0)的Logistic迴歸/線性層瘋狂高的梯度傳回。對於圓圈(標籤1,預測0),值大致在-12和-5之間,但對於十字架,它們都處於正高1000到高2000範圍內。
,它發送這些後面的代碼看起來是這樣(部分省略):
void LinearClassifier::Train(float * x,float output, float y)
{
float h = output - y;
float average = 0.0f;
for (int i =1; i < m_NumberOfWeights; ++i)
{
float error = h*x[i-1];
m_pGradients[i-1] = error;
average += error;
}
average /= static_cast<float>(m_NumberOfWeights-1);
for (int theta = 1; theta < m_NumberOfWeights; ++theta)
{
m_pWeights[theta] = m_pWeights[theta] - learningRate*m_pGradients[theta-1];
}
// Bias
m_pWeights[0] -= learningRate*average;
}
這被傳遞迴單卷積層:
// This code is in three nested for loops (for layer,for outWidth, for outHeight)
float gradient = 0.0f;
// ReLu Derivative
if (m_pOutputBuffer[outputIndex] > 0.0f)
{
gradient = outputGradients[outputIndex];
}
for (int z = 0; z < m_InputDepth; ++z)
{
for (int u = 0; u < m_FilterSize; ++u)
{
for (int v = 0; v < m_FilterSize; ++v)
{
int x = outX + u - 1;
int y = outY + v - 1;
int inputIndex = x + y*m_OutputWidth + z*m_OutputWidth*m_OutputHeight;
int kernelIndex = u + v*m_FilterSize + z*m_FilterSize*m_FilterSize;
m_pGradients[inputIndex] += m_Filters[layer][kernelIndex]*gradient;
m_GradientSum[layer][kernelIndex] += input[inputIndex]*gradient;
}
}
}
該代碼是通過使遍歷每個圖像一次一個地呈現。漸變顯然是朝着正確的方向發展,但是如何阻止巨大的漸變投擲預測函數?