Python 如何在nolearn,lasagne中定义成本函数?

Python 如何在nolearn,lasagne中定义成本函数?,python,theano,lasagne,nolearn,Python,Theano,Lasagne,Nolearn,我在nolearn做一个神经网络,一个基于Theano的图书馆,使用千层面 我不明白如何定义自己的成本函数 输出层只有3个神经元[0,1,2],我希望它在给出1或2时能大致确定,否则-如果它不确定1,2-只返回0 因此,我提出了一个成本函数(需要调整),其中1和2的成本是0的两倍,但我不明白如何将此告诉网络 # optimization method: from lasagne.updates import sgd update=sgd, update_learning_rate=0.0001

我在nolearn做一个神经网络,一个基于Theano的图书馆,使用千层面

我不明白如何定义自己的成本函数

输出层只有3个神经元
[0,1,2]
,我希望它在给出1或2时能大致确定,否则-如果它不确定1,2-只返回0

因此,我提出了一个成本函数(需要调整),其中1和2的成本是0的两倍,但我不明白如何将此告诉网络

# optimization method:
from lasagne.updates import sgd
update=sgd,
update_learning_rate=0.0001
这是更新的代码,但是我如何告诉SGD使用我的成本函数而不是它自己的

编辑: 完整的网络代码为:

def nn_loss(data, x_period, columns, num_epochs, batchsize, l_rate=0.02):
    net1 = NeuralNet(
        layers=[('input', layers.InputLayer),
                ('hidden1', layers.DenseLayer),
                ('output', layers.DenseLayer),
                ],
        # layer parameters:
        batch_iterator_train=BatchIterator(batchsize),
        batch_iterator_test=BatchIterator(batchsize),

        input_shape=(None, int(x_period*columns)),
        hidden1_nonlinearity=lasagne.nonlinearities.rectify,
        hidden1_num_units=100,  # number of units in 'hidden' layer
        output_nonlinearity=lasagne.nonlinearities.sigmoid,
        output_num_units=3,

        # optimization method:
        update=nesterov_momentum,
        update_learning_rate=5*10**(-3),
        update_momentum=0.9,
        on_epoch_finished=[
            EarlyStopping(patience=20),
        ],
        max_epochs=num_epochs,
        verbose=1,

        # Here are the important parameters for multi labels
        regression=True,
        # objective_loss_function=multilabel_objective,
        # custom_score=("validation score", lambda x, y: np.mean(np.abs(x - y)))
        )

    # Train the network
    start_time = time.time()
    net1.fit(data['X_train'], data['y_train'])
}
编辑 使用回归=真时出错

Got 99960 testing datasets.
# Neural Network with 18403 learnable parameters

## Layer information

  #  name       size
---  -------  ------
  0  input       180
  1  hidden1     100
  2  output        3

Traceback (most recent call last):
  File "/Users/morgado/anaconda/lib/python3.4/site-packages/theano/compile/function_module.py", line 607, in __call__
    outputs = self.fn()
ValueError: GpuElemwise. Input dimension mis-match. Input 1 (indices start at 0) has shape[1] == 1, but the output's size on that axis is 3.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "train_nolearn_simple.py", line 272, in <module>
    main(**kwargs)
  File "train_nolearn_simple.py", line 239, in main
    nn_loss_fit = nn_loss(data, x_period, columns, num_epochs, batchsize)
  File "train_nolearn_simple.py", line 217, in nn_loss
    net1.fit(data['X_train'], data['y_train'])
  File "/Users/morgado/anaconda/lib/python3.4/site-packages/nolearn/lasagne/base.py", line 416, in fit
    self.train_loop(X, y)
  File "/Users/morgado/anaconda/lib/python3.4/site-packages/nolearn/lasagne/base.py", line 462, in train_loop
    self.train_iter_, Xb, yb)
  File "/Users/morgado/anaconda/lib/python3.4/site-packages/nolearn/lasagne/base.py", line 516, in apply_batch_func
    return func(Xb) if yb is None else func(Xb, yb)
  File "/Users/morgado/anaconda/lib/python3.4/site-packages/theano/compile/function_module.py", line 618, in __call__
    storage_map=self.fn.storage_map)
  File "/Users/morgado/anaconda/lib/python3.4/site-packages/theano/gof/link.py", line 297, in raise_with_op
    reraise(exc_type, exc_value, exc_trace)
  File "/Users/morgado/anaconda/lib/python3.4/site-packages/six.py", line 658, in reraise
    raise value.with_traceback(tb)
  File "/Users/morgado/anaconda/lib/python3.4/site-packages/theano/compile/function_module.py", line 607, in __call__
    outputs = self.fn()
ValueError: GpuElemwise. Input dimension mis-match. Input 1 (indices start at 0) has shape[1] == 1, but the output's size on that axis is 3.
Apply node that caused the error: GpuElemwise{Sub}[(0, 1)](GpuElemwise{Composite{scalar_sigmoid((i0 + i1))}}[(0, 0)].0, GpuFromHost.0)
Toposort index: 22
Inputs types: [CudaNdarrayType(float32, matrix), CudaNdarrayType(float32, matrix)]
Inputs shapes: [(200, 3), (200, 1)]
Inputs strides: [(3, 1), (1, 0)]
Inputs values: ['not shown', 'not shown']
Outputs clients: [[GpuCAReduce{pre=sqr,red=add}{1,1}(GpuElemwise{Sub}[(0, 1)].0), GpuElemwise{Mul}[(0, 0)](GpuElemwise{Sub}[(0, 1)].0, GpuElemwise{Composite{scalar_sigmoid((i0 + i1))}}[(0, 0)].0, GpuElemwise{sub,no_inplace}.0), GpuElemwise{mul,no_inplace}(CudaNdarrayConstant{[[ 2.]]}, GpuElemwise{Composite{(inv(i0) / i1)},no_inplace}.0, GpuElemwise{Sub}[(0, 1)].0, GpuElemwise{Composite{scalar_sigmoid((i0 + i1))}}[(0, 0)].0, GpuElemwise{sub,no_inplace}.0)]]

HINT: Re-running with most Theano optimization disabled could give you a back-trace of when this node was created. This can be done with by setting the Theano flag 'optimizer=fast_compile'. If that does not work, Theano optimizations can be disabled with 'optimizer=None'.
HINT: Use the Theano flag 'exception_verbosity=high' for a debugprint and storage map footprint of this apply node.
获得了99960个测试数据集。
#具有18403个可学习参数的神经网络
##层信息
#名称大小
---  -------  ------
0输入180
1隐藏1100
2产出3
回溯(最近一次呼叫最后一次):
文件“/Users/morgado/anaconda/lib/python3.4/site packages/theano/compile/function\u module.py”,第607行,在调用中__
输出=self.fn()
ValueError:gpuelWise。输入尺寸不匹配。输入1(索引从0开始)的形状[1]==1,但该轴上的输出大小为3。
在处理上述异常期间,发生了另一个异常:
回溯(最近一次呼叫最后一次):
文件“train\u nolearn\u simple.py”,第272行,在
主要(**kwargs)
文件“train\u nolearn\u simple.py”,第239行,在main中
nn_损耗_拟合=nn_损耗(数据、x_周期、列、数字时代、批次大小)
文件“train\u nolearn\u simple.py”,第217行,在nn\u loss中
net1.fit(数据['X_-train'],数据['y_-train'])
文件“/Users/morgado/anaconda/lib/python3.4/site packages/nolearn/lasagne/base.py”,第416行,适合
自循环列车(X,y)
文件“/Users/morgado/anaconda/lib/python3.4/site packages/nolearn/lasagne/base.py”,第462行,列车循环中
自我训练(iter、Xb、yb)
文件“/Users/morgado/anaconda/lib/python3.4/site packages/nolearn/lasagne/base.py”,第516行,在apply\u batch\u func中
如果yb不是其他func(Xb,yb),则返回func(Xb)
文件“/Users/morgado/anaconda/lib/python3.4/site packages/theano/compile/function\u module.py”,第618行,在调用中__
存储映射=self.fn.storage映射)
文件“/Users/morgado/anaconda/lib/python3.4/site packages/theano/gof/link.py”,第297行,用
重新释放(exc_类型、exc_值、exc_跟踪)
文件“/Users/morgado/anaconda/lib/python3.4/site packages/six.py”,第658行,在reraise中
通过_回溯(tb)提升值
文件“/Users/morgado/anaconda/lib/python3.4/site packages/theano/compile/function\u module.py”,第607行,在调用中__
输出=self.fn()
ValueError:gpuelWise。输入尺寸不匹配。输入1(索引从0开始)的形状[1]==1,但该轴上的输出大小为3。
导致错误的应用节点:GpuElemwise{Sub}[(0,1)](GpuElemwise{Composite{scalar_sigmoid((i0+i1))}[(0,0)].0,GpuFromHost.0)
拓扑排序索引:22
输入类型:[CudaNdarrayType(浮点32,矩阵),CudaNdarrayType(浮点32,矩阵)]
输入形状:[(200,3)、(200,1)]
输入跨步:[(3,1)、(1,0)]
输入值:[“未显示”、“未显示”]
输出客户:[[GPucuca减少{pre=sqr,红色=加上{{{1,1}(1,0,1)1}(0,1)0),GPUElelemi{{Mul}[(0,0,0)0,GPucucuca减少{{1,1,红色=客户输出客户:[[GPucucuca减少{{{{{{{Sub}(0,1(0,1)(1,1)1)1)1}(1,1}(1,1,1)1)1}(1,1)1)1}(1)1)1)0,0,(0,(0,0,(0,0,0,0,0,0,0,0,0,0)0)0)0)0,0,0,0.0,0,0.0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,i0)/i1)},没有位置}.0,GpuElemwise{Sub}[(0,1)].0,GpuElemwise{Composite{scalar_sigmoid((i0+i1))}[(0,0)].0,GpuElemwise{Sub,no_inplace}.0]]
提示:在禁用大多数Theano优化的情况下重新运行可能会返回此节点创建的时间。这可以通过设置Theano标志“optimizer=fast\u compile”来完成。如果不起作用,可以使用“optimizer=None”禁用无优化。
提示:对此应用节点的调试打印和存储映射示意图使用Theano标志“exception\u verbosity=high”。
请参见以下示例(摘自),该示例指定了其自身的损失函数:

import lasagne
import theano.tensor as T
import theano
from lasagne.nonlinearities import softmax
from lasagne.layers import InputLayer, DenseLayer, get_output
from lasagne.updates import sgd, apply_momentum
l_in = InputLayer((100, 20))
l1 = DenseLayer(l_in, num_units=3, nonlinearity=softmax)
x = T.matrix('x')  # shp: num_batch x num_features
y = T.ivector('y') # shp: num_batch
l_out = get_output(l1, x)
params = lasagne.layers.get_all_params(l1)
loss = T.mean(T.nnet.categorical_crossentropy(l_out, y))
updates_sgd = sgd(loss, params, learning_rate=0.0001)
updates = apply_momentum(updates_sgd, params, momentum=0.9)
train_function = theano.function([x, y], updates=updates)

巧合的是,这段代码在输出层中也有三个单元。

当你实例化你的神经网络时,你可以传递一个你之前定义的自定义损失函数:

import theano.tensor as T
import numpy as np
from nolearn.lasagne import NeuralNet
# I'm skipping other inputs for the sake of concision

def multilabel_objective(predictions, targets):
    epsilon = np.float32(1.0e-6)
    one = np.float32(1.0)
    pred = T.clip(predictions, epsilon, one - epsilon)
    return -T.sum(targets * T.log(pred) + (one - targets) * T.log(one - pred), axis=1)

net = NeuralNet(
    # your other parameters here (layers, update, max_epochs...)
    # here are the one you're interested in:
    objective_loss_function=multilabel_objective,
    custom_score=("validation score", lambda x, y: np.mean(np.abs(x - y)))
    )

如您所见,还可以定义自定义分数(使用关键字
custom_score

我在分类任务中使用了自定义损失函数,我想我也会与您分享。我基本上希望根据标签对训练数据进行不同的强调

import lasagne
import theano.tensor as T
import theano

def weighted_crossentropy(predictions, targets):

  weights_per_label = theano.shared(lasagne.utils.floatX([0.2, 0.4, 0.4]))
  weights = weights_per_label[targets]  #returns a targets-shaped weight matrix
  loss = lasagne.objectives.aggregate(T.nnet.categorical_crossentropy(predictions, targets), weights=weights)
  return loss

net = NeuralNet(
    # layers and parameters
    objective_loss_function=weighted_crossentropy,
    # ...
    )

是我发现如何实现它的地方。

谢谢,这是我一直在寻找的。在实现此功能后,新的损失函数只接受2的批量大小存在问题。我已经用代码更新了这个问题。@jbssm这在我的代码中批量大小为128时可以正常工作,您能在问题中包含错误消息吗?请同时包括X_train.shape和y_train.shape。实际上,问题不是您的代码。我删除了“多标签”目标,问题仍然存在。我在将网络从使用编目改为使用回归时犯了一些错误,这应该是现在的问题。@jbssm您的输入和输出形状是什么?另外,为什么不可接受是问题的根源在其他地方,谢谢我想这会帮助我解决这个问题。