Пытаясь вычислить значения softmax, получаем AttributeError: объект 'list' не имеет атрибута 'T'


Во-первых, вот мой код:

"""Softmax."""

scores = [3.0, 1.0, 0.2]

import numpy as np

def softmax(x):
    """Compute softmax values for each sets of scores in x."""
    num = np.exp(x)
    score_len = len(x)
    y = [0] * score_len
    for index in range(1,score_len):
        y[index] = (num[index])/(sum(num))
    return y

print(softmax(scores))

# Plot softmax curves
import matplotlib.pyplot as plt
x = np.arange(-2.0, 6.0, 0.1)
scores = np.vstack([x, np.ones_like(x), 0.2 * np.ones_like(x)])

plt.plot(x, softmax(scores).T, linewidth=2)
plt.show()

Теперь, глядя на это вопрос, я могу сказать, что T-это транспонирование моем списке. Тем не менее, я, кажется, получаю ошибку:

AttributeError: объект 'list' не имеет атрибута ' T '

Я не понимаю, что здесь происходит. Неужели мое понимание всей этой ситуации неверно? Я пытаюсь пройти курс Google Deep Learning, и я думал, что смогу использовать Python, реализуя программы, но я может, и ошибся. В настоящее время я знаю много других языков, таких как C и Java, но новый синтаксис всегда сбивает меня с толку.
2 3

2 ответа:

Посмотрите на тип и форму переменных в вашем коде

x является 1D массивом; scores является 2d (3 строки):

In [535]: x.shape
Out[535]: (80,)
In [536]: scores.shape
Out[536]: (3, 80)

softmax производит список из 3 элементов; первый-это число 0, остальные-массивы с формой, подобной x.

In [537]: s=softmax(scores)
In [538]: len(s)
Out[538]: 3
In [539]: s[0]
Out[539]: 0
In [540]: s[1].shape
Out[540]: (80,)
In [541]: s[2].shape
Out[541]: (80,)

Ожидали ли вы, что softmax создаст массив с той же формой, что и его входные данные, в данном случае a (3,80).

num=np.exp(scores)
res = np.zeros(scores.shape)
for i in range(1,3):
    res[i,:]= num[i,:]/sum(num)

Создает двумерный массив, который можно транспонировать и построить на графике.

Но вы не должны делать это ряд за рядом. Вы действительно хотите, чтобы 1-я строка res была 0?
res = np.exp(scores)
res = res/sum(res)
res[0,:] = 0    # reset 1st row to 0?

Почему вы выполняли векторизованную операцию над каждой строкой scores, но не над всем объектом?

Как описано в комментариях, важно, чтобы выходные данные softmax(scores) были массивом, поскольку списки не имеют атрибута .T. Поэтому, если мы заменим соответствующие биты в вопросе кодом ниже, мы снова сможем получить доступ к атрибуту .T.

num = np.exp(x)
score_len = len(x)
y = np.array([0]*score_len)
Следует отметить, что мы должны использовать np.array, поскольку не numpy библиотеки обычно не работают с обычными библиотеками python.