Это не совсем понятно, что вы пытаясь сделать здесь, но я предполагаю, что вы реализуете две разные версии линейного классификатора, которые не используют сканирование, а другое - это.
Приведенный ниже код демонстрирует мой подход к этому.
Чтобы ответить на ваш конкретный вопрос:
Сообщение об ошибке появляется потому, что ваша версия сканирования использует T_f
в ступенчатую функцию сканирования (это странно и одна причина, не ясно, что вы пытаетесь сделать, шаг функция не использует ни одну из своих входных переменных x
, W
, или b
вообще!) и T_f
использует T_x
, но функция сканирования не принимает T_x
в качестве входных данных. Вместо этого требуется T_X
(обратите внимание на разницу в случае), который тогда не используется вообще.
Вот несколько советов и объяснений различий между вашим кодом и моим.
Это очень помогает держать вещи разделенными на дискретные методы. Разделив код на методы v1
и v2
, мы гарантируем, что две разные реализации не мешают друг другу.
Использование параметра strict
параметра theano.scan
рекомендуется в любое время. Это гарантирует, что вы случайно не внесете ошибку, вызванную конфликтами имен в параметрах функции шага. Он не включен по умолчанию, потому что это может привести к повреждению старого кода, когда строгого не существует.
Используйте полноценную функцию вместо лямбда для функции шага сканирования. Подобно строгому режиму, это помогает избежать случайных конфликтов имен и упрощает выполнение кода шага. Функция шага также может быть проверена изолированно.
Используйте compute_test_value
, чтобы обеспечить выполнение расчетов с использованием простых данных образца. В частности, это будет определять несоответствия формы (например, делать dot
с параметрами в неправильном порядке) и облегчает отладку, имея возможность печатать/исследовать промежуточные значения , в то время как граф вычислений строит, а не позже, когда выполняется вычисление.
Этот код имеет каждый образец ввода, закодированный как строка x
, а не как столбец x
. Это требует повторного умножения на w
вместо предварительного умножения.Это можно сделать в любом случае, но предварительное умножение на w
сделает добавление с b
бит messier (необходимо ввести dimshuffle
).
Там нет необходимости использовать theano.Param
, если нет необходимости использовать не стандартное поведение по отношению к значениям по умолчанию, и т.д.
Избегайте называть вещи таким образом, что они отличаются только в случае! В общем случае придерживайтесь Python style guide (то есть переменные экземпляра должны быть в нижнем регистре со словами, разделенными символами подчеркивания).
В шаговой функции версии сканирования требуется искажение и выбор первой строки, чтобы обеспечить точечный продукт и подпоследовательность добавления смещения совместимы по размерности. Это не требуется в версии без сканирования, потому что мы делаем матричный матричный dot-продукт.
Код:
import numpy
import theano
import theano.tensor as T
def create_inputs(x_value, w_value, b_value):
x, w = T.matrices(2)
b = T.vector()
x.tag.test_value = x_value
w.tag.test_value = w_value
b.tag.test_value = b_value
return x, w, b
def v1(x_value, w_value, b_value):
x, w, b = create_inputs(x_value, w_value, b_value)
y = T.dot(x, w) + b
f = theano.function(inputs=[x, w, b], outputs=y)
print f(x_value, w_value, b_value)
def v2_step(x, w, b):
return (T.dot(x.dimshuffle('x', 0), w) + b)[0]
def v2(x_value, w_value, b_value):
x, w, b = create_inputs(x_value, w_value, b_value)
y, _ = theano.scan(v2_step, sequences=[x], non_sequences=[w, b], strict=True)
f = theano.function(inputs=[x, w, b], outputs=y)
print f(x_value, w_value, b_value)
def main():
batch_size = 2
input_size = 3
hidden_size = 4
theano.config.compute_test_value = 'raise'
numpy.random.seed(1)
x_value = numpy.random.standard_normal(size=(batch_size, input_size))
w_value = numpy.random.standard_normal(size=(input_size, hidden_size))
b_value = numpy.zeros((hidden_size,))
v1(x_value, w_value, b_value)
v2(x_value, w_value, b_value)
main()
@KevinGuan: Я новичок в политике StackOverflow: «Может ли кто-нибудь помочь мне узнать, что я делаю неправильно» вы можете объяснить, почему вы редактировали вопрос извлекая – mzs
Потому что SO - это сайт Q & A. Здесь все задают вопрос, потому что у них проблемы. Поэтому вам не нужно говорить что-то такое, как я удалил. Снова: * Все знают, что вы поступаете неправильно, поэтому вам не нужно говорить об этом в своем вопросе. * :) –
Также не нужно говорить «спасибо», и вы этого не сделали, так что это просто подсказка. –