- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我从头开始创建了一个用于二元分类的简单神经网络(灵感来自 Andrew Ng 的一个类的实现)。但是,我认为我在某处弄错了反向传播部分,因为梯度下降未能最小化成本。在这个例子中,在大约第 1300 次迭代之后,dJ/dW 变为 NaN(随后,W 也变为 NaN)。我仔细检查了我的方程式,但我不知道我在哪里犯了错误。有任何想法吗?
我的代码:
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
class BinaryClassifier:
def __init__(self, X, Y, hidden_layers, num_iterations, learning_rate=1.2):
np.random.seed(1)
self.X = X
self.Y = Y
self.Z = {}
self.A = {}
self.W = {}
self.b = {}
self.dZ = {} # dJ/dZ (derivative with respect to Z)
self.dA = {} # dJ/dA (derivative with respect to A)
self.dW = {} # dJ/dW (derivative with respect to W)
self.db = {} # dJ/db (derivative with respect to b)
self.m = self.Y.shape[1] # number of training examples
# hyper parameters:
self.layers = hidden_layers + [1] # the final layer in logestic regression will be a single logistic unit
self.L = len(self.layers) # number of layers (not counting the input layer)
self.num_iterations = num_iterations
self.learning_rate = learning_rate
##### initialize parameters: #####
nodes_prev_layer = self.X.shape[0] # get number of nodes from input layer
for layer, nodes in enumerate(self.layers):
# n.b. scale `W` with Xavier/He initialization:
self.W[layer+1] = np.random.randn(nodes, nodes_prev_layer) * np.sqrt(2/nodes_prev_layer)
self.b[layer+1] = np.zeros((nodes, 1))
nodes_prev_layer = nodes
###### utility functions: #####
def relu_function(self, Z):
return np.maximum(Z, 0)
def sigmoid_function(self, Z):
return 1/(1 + np.exp(-Z))
def relu_gradient(self, Z):
return np.where(Z > 0, 1, 0)
def sigmoid_gradient(self, Z):
return self.sigmoid_function(Z) * (1 - self.sigmoid_function(Z))
##### forward propagation steps: #####
def linear_forward(self, A_prev, W, b, activation):
""" Forward step (linear + activation) for single layer.
"""
Z = np.dot(W, A_prev) + b
if activation == 'relu':
A = self.relu_function(Z)
elif activation == 'sigmoid':
A = self.sigmoid_function(Z)
else:
raise ValueError('Invalid activation function: %s' % activation)
assert A.shape == Z.shape
return A, Z
def forward_propagation(self):
""" Feed forward through all layers.
"""
# the 'activated' unit for layer 0 is just the input:
self.A[0] = np.copy(self.X)
# propagate and compute activations for hidden layers
for l in range(1, self.L+1):
if l < self.L:
activation = 'relu'
# use last layer for logistic activation:
else:
activation = 'sigmoid'
self.A[l], self.Z[l] = self.linear_forward(self.A[l-1], self.W[l], self.b[l], activation)
AL = self.A[self.L]
return AL
def compute_cost(self, Y_hat):
cost = -1/self.m * np.sum( (self.Y*np.log(Y_hat)) + ((1-self.Y) * np.log(1-Y_hat)) )
cost = np.squeeze(cost)
assert(cost.shape == ())
return cost
##### backward propagation steps: #####
def linear_backward(self, A_prev, dA, W, Z, b, activation='relu'):
""" Backward propagation (activation + linear) for a single layer.
"""
if activation == 'relu':
dZ = dA * self.relu_gradient(Z)
elif activation == 'sigmoid':
dZ = dA * self.sigmoid_gradient(Z)
else:
raise ValueError('Invalid activation function: %s' % activation)
dW = 1/self.m * np.dot(dZ, A_prev.T)
db = 1/self.m * np.sum(dZ, axis=1, keepdims=True)
dA_prev = np.dot(W.T, dZ) # dA for the previous layer (dA[l-1])
assert dA_prev.shape == A_prev.shape
assert dW.shape == W.shape
return dA_prev, dZ, dW, db
def backward_propagation(self):
""" Backward propagation for all layers.
"""
for l in reversed(range(1, self.L+1)):
if l == self.L:
self.dA[l] = -(np.divide(self.Y, self.A[l]) - np.divide(1-self.Y, 1-self.A[l]))
activation = 'sigmoid'
else:
activation = 'relu'
self.dA[l-1], self.dZ[l], self.dW[l], self.db[l] = self.linear_backward(self.A[l-1], self.dA[l], self.W[l], self.Z[l], self.b[l], activation)
def update_parameters(self):
""" Updtes W and b parameters after single iteration of backprop.
"""
for l in range(1, self.L+1):
self.W[l] -= (self.learning_rate * self.dW[l])
self.b[l] -= (self.learning_rate * self.db[l])
##### train/predict methods: #####
def train_binary_classification_model(self, print_cost=True):
""" Trains model and updates parameters.
"""
np.random.seed(1)
for i in range(self.num_iterations):
AL = self.forward_propagation()
if print_cost and i % 500 == 0:
cost = self.compute_cost(AL)
print('cost at %s iterations: %s' % (i, cost))
self.backward_propagation()
self.update_parameters()
def predict(self):
AL = self.forward_propagation()
return np.where(AL > 0.5, 1, 0)
并生成样本数据并训练模型:
def generate_data():
np.random.seed(1)
m = 400 # number of examples
N = int(m/2) # number of points per class
D = 2 # dimensionality
X = np.zeros((m,D)) # data matrix where each row is a single example
Y = np.zeros((m,1), dtype='uint8') # labels vector (0 for red, 1 for blue)
a = 4 # maximum ray of the flower
for j in range(2):
ix = range(N*j,N*(j+1))
t = np.linspace(j*3.12,(j+1)*3.12,N) + np.random.randn(N)*0.2 # theta
r = a*np.sin(4*t) + np.random.randn(N)*0.2 # radius
X[ix] = np.c_[r*np.sin(t), r*np.cos(t)]
Y[ix] = j
X = X.T
Y = Y.T
return X, Y
########################################
# main:
########################################
X, Y = generate_data()
# train a binary classifcation model with a single hidden layer (4 nodes):
planar_network = BinaryClassifier(X, Y, [4], 4000, learning_rate=1.2)
planar_network.train_binary_classification_model()
# output:
# cost at 0 iterations: 0.9897586239010666
# cost at 500 iterations: 0.5513227406119928
# cost at 1000 iterations: 0.5457089978185676
# cost at 1500 iterations: nan
# cost at 2000 iterations: nan
# ...
最佳答案
您收到 cost = nan
因为在您的任何步骤中,它都遇到了无效值。
在这个网络中可能有两个原因:
log(0)
number/0
self.epsilon = 0.00001
compute_cost
: def compute_cost(self, Y_hat):
cost = -1/self.m * np.sum( (self.Y*np.log(Y_hat+self.epsilon)) + ((1-self.Y) * np.log(1-Y_hat+self.epsilon)) )
cost = np.squeeze(cost)
assert(cost.shape == ())
return cost
backward_propagation
: def backward_propagation(self):
""" Backward propagation for all layers.
"""
for l in reversed(range(1, self.L+1)):
if l == self.L:
self.dA[l] = -(np.divide(self.Y, self.A[l]+self.epsilon) - np.divide(1-self.Y, 1-self.A[l]+self.epsilon))
activation = 'sigmoid'
else:
activation = 'relu'
self.dA[l-1], self.dZ[l], self.dW[l], self.db[l] = self.linear_backward(self.A[l-1], self.dA[l], self.W[l], self.Z[l], self.b[l], activation)
self.epsilon
在出现无效值的情况下。
关于python - 如何从头开始调试反向传播实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63376932/
我能否获得一个具有两个参数的递归Prolog谓词,称为反向,它返回列表的反向: 示例查询和预期结果: α-反向([a,b,c],L)。 L = [c,b,a]。 由两个称为palindrome的参数组
在使用 get_dummies() 将分类数据转换为数字数据后,我的数据框看起来像这样 score1 score2 country_CN country _AU category_leader ca
我有一张 table ,上面有一个国家/地区列表。说这些国家之一是“马其顿” 如果搜索“马其顿共和国”,什么 SQL 查询会返回“马其顿”记录? 我相信在 linq 中它会是这样的 var count
我们有一个角色继承结构,它假设每个人都默认获得最低级别的角色,而不是最高级别的过滤,如下图所示: role.Everyone //lowest level; everyone gets this ro
我正在使用 $.each() 解析数组,但在其中,我使用 .splice() 方法,因此我需要向后迭代。这可能吗? var store = [...]; //... var rules = [...]
我有一个 SPLObjectStorage 对象,其中 Player 对象作为键,分数作为与之关联的信息。玩家对象按照从最高分到最低分的顺序添加到存储中,但我现在需要以相反的顺序遍历它们。 我还需要能
我无法理解这一点:如果我给 Prolog reverse([], A). 它工作得很好,如果我给它 reverse(A, [] ). 并根据第一个建议回答 ; 它挂起!为什么? (GNU Prolog
我有一个 SPLObjectStorage 对象,其中 Player 对象作为键,分数作为与之关联的信息。玩家对象按照从最高分到最低分的顺序添加到存储中,但我现在需要以相反的顺序遍历它们。 我还需要能
我有一个HashMap看起来像: HashMap playerHashMap = new HashMap<>(); 玩家是包含姓名、号码、年龄等的对象。 现在我已经对它进行了排序,它看起来像这样: k
我有这个: file://localhost/Volumes/Untitled%20RAID%20Set%201/Callum/iTunes/Music/Steppenwolf/Steppenwolf
我正在使用 std::regex 并希望找到与某个用户定义的正则表达式字符串匹配的字符串中的最后一个位置。 例如,给定正则表达式 :.* 和字符串“test:55:last”,我想找到“:last”,
有一个表 ServErog(服务),它被重新引导到 4 个表 ServA、ServB、ServC、ServD(它们是不同的非统一服务),其中包含 servtype(服务类型)和 type_id(来自其
这个问题在这里已经有了答案: What is the best way to convert date from JavaScript string in format YYYYMMDD to Ja
我知道如何获得包含几个词的所有结果: SELECT * FROM `table` WHERE MATCH (`row`) AGAINST ('+word1 +word2' IN BOOLEAN MOD
你好,我有这个 html 代码: .container{ width: 450; height: 400; border:1px solid
我想知道是否有任何方法可以使用相同的 CSS 过渡实例来将其向前移动然后向后/向后移动。例如,假设我有这种转变: @-webkit-keyframes fade-transition { fr
假设我有这些字符串: char ref[30] = "1234567891234567891"; char oth[30] = "1234567891234567891"; 我想在 C++ 中使用 S
所以我有这段代码,它使 xcode 崩溃 void strrev(const std::string& str) { for(size_t i=str.length();i>=0;i--)
我正在使用下面的代码使每张图片 1 对 1 淡入淡出。我怎样才能反向执行此操作以使图片以相反的顺序加载? img {display:none;} $('img').each(function(
我正在尝试弄清楚如何改变 FrameLayout 堆叠其子项的方式。 目前它是最新的(先进先出)。我想更改它,使最新的 child 位于底部(FILO)。我试着查看 FrameLayout 的源代码,
我是一名优秀的程序员,十分优秀!