Съдържание на курса

Тензори от нулата (2): твоят първи тензор

От · основател и главен изпълнителен директор на Hábil ·

Обновено на 21 октомври 2026 г.

Инсталираш PyTorch, превръщаш книжарницата на доня Лупе в истински тензор и откриваш, че функцията, която програмира миналата седмица, вече е вградена.

Тензори от нулата · урок A, сесия 2 от 8

Сценарий: героите и историята са измислени. Техническите и историческите данни и реалните цифри са с посочен източник.

Понеделник, 9 ноември, 7:40 вечерта. Задната стая на клона Centro.

Мирише на нова хартия и на претоплено кафе. Доня Лупе спуска металната ролетка наполовина, с онова стържене, което се чува чак до ъгъла, и сяда до Матео.

— Файлът от Norte дойде — казва и слага телефона пред него. — Седмичният. Той ме интересува.

Матео го прехвърля на лаптопа си. Седем дни, три продукта: тетрадки, химикалки и раници. Както винаги. На календара на стената някой е оградил в червено 23 декември. Остават четиридесет и четири дни.

— И сега какво ще му правиш? Пак ли твоите списъчета?

Миналата седмица Матео записа книжарницата като списъци в списъци и програмира ръчно две функции: едната брои измеренията, другата изчислява формата. Работеха. Но откри и нещо неудобно: функцията му forma се оставя да бъде излъгана от крив списък. И не предупреждава.

— Списъците вече не ми стигат, лельо. Трябва ми истински инструмент.

— И колко струва?

— Нищо. Безплатен е.

Доня Лупе го поглежда над очилата.

— Евтиното излиза скъпо, моето момче.

— Този не. С него работят хората, които правят изкуствен интелект.

— Още по-зле.

Матео се смее и отваря терминала. Но преди да инсталира каквото и да е, си поставя правило: да отговори на трите въпроса от миналата седмица, без да поглежда бележките си. Ако не може, няма смисъл да продължава. Нов инструмент върху слаба основа само прави грешките по-бързо.

Преговор за начало

Преди да започнеш, отговори, без да поглеждаш сесия 1. Отговорите са в края, в решенията.

  1. Как разбираш колко измерения има един набор от данни, без да броиш скоби?
  2. Какво ти казва формата (2, 7, 3) и колко числа има общо?
  3. Какво условие трябва да изпълнява един списък от списъци, за да бъде тензор?

Ако си се поколебал на някой от тях, върни се на сесия 1, преди да продължиш.

Кодът на тази сесия е в публичното хранилище на курса, в папката sesion-02: github.com/HabilMX/curso-tensores. Първо го напиши сам, защото така се учи; хранилището е за сравнение, когато нещо не ти излезе по същия начин. Всяка програма идва с изхода, който трябва да получиш.

Цели на тази сесия

В края ще можеш да правиш тези пет неща. До всяко е упражнението, което го доказва.

# В края можеш… Доказва го
1 Да инсталираш PyTorch в собствена среда и да провериш, че работи Стъпка 1 и упражнение 6
2 Да превърнеш вложените си списъци в тензор с torch.tensor Упражнения 7 и 8
3 Да разчетеш формата, измеренията и общия брой числа на тензор (.shape, .ndim, .numel()) и да ги провериш с assert срещу функциите си от сесия 1 Упражнения 6, 7 и 8
4 Да предвидиш типа на числата в тензор (.dtype) и сам да го избереш, когато трябва Упражнения 6 и 8
5 Да разчетеш грешката, която PyTorch дава при крив списък, и да кажеш къде е проблемът Упражнение 9

Какво ти трябва: завършена сесия 1, с файла ти dimensiones.py (списъците на книжарницата и функциите contar_dimensiones и forma). Компютър с Linux Mint (или какъвто и да е Linux или macOS с Python 3.11 или по-нов; на Windows курсът не е изпробван), интернет, за да изтеглиш PyTorch, и отворен терминал.


Защо е важно

Матео отново поглежда функцията си forma. Един while, един append, един tuple. Сработи с книжарницата. Но има дупка: при крив списък лъже. И лъже много самоуверено.

Това не му дава мира. Ако файлът от Norte дойде сгрешен, функцията му ще му даде форма, без да мигне, и той ще ѝ повярва. А ако файлът съдържа милион числа, всяко изчисление ще бъде поредният for, написан ръчно.

Който работи с изкуствен интелект, не програмира тези функции всеки път. Използва библиотека, която вече пази числата подредени, знае формата им, проверява дали са правоъгълни и смята много бързо. Най-използваната в научните изследвания се казва PyTorch.

Днес научаваш първото, което прави всеки, който работи с ИИ, когато получи нови данни: създава тензора и го пита какъв е. Каква форма има? Колко измерения? Колко числа? От какъв тип? Ако отговорите не са тези, които очакваш, нищо от онова, което следва, няма да излезе както трябва.

Матео още не го знае, но тази вечер един от тези въпроси ще получи отговор „не“.


Стъпка 1 — Инсталиране на PyTorch

Отделна стая за инструментите ти

Преди да инсталираш, ще създадеш виртуална среда. Звучи сложно, но не е: това е папка, в която пазиш библиотеките на един проект, отделно от тези на останалата част от компютъра ти.

Представи си я като кутията с инструменти на чичо ти водопроводчика: ако той сложи ключовете си в кухненското чекмедже, един ден няма да намери нищо. Със собствена кутия никой не му пипа нищо. Виртуалната среда е твоята кутия: каквото инсталираш там, не пречи на Linux Mint, който използва собствения си Python, за да работи.

В терминала първо провери версията си на Python:

python3 --version

Трябва ти 3.11 или по-нова: това изисква PyTorch от версия 2.15 нататък. Linux Mint 22 идва с Python 3.12, така че си наред.

В Linux Mint и Ubuntu първо това. Инструментът за създаване на среди е в отделен пакет, който новата инсталация няма. Инсталирай го (ще ти поиска паролата); ако вече го имаш, нищо не става:

sudo apt install python3-venv

Сега създай средата и я активирай:

python3 -m venv ~/tensores
source ~/tensores/bin/activate

Първият ред създава кутията: папка, наречена tensores, в личната ти папка (това означава ~). Вторият я отваря. Ще забележиш, че терминалът ти вече започва с (tensores). Това е знакът, че си вътре.

Ако използваш Windows: тези два реда са за Linux и macOS. В Windows, от личната си папка, създай средата с python -m venv tensores и я отвори с .\tensores\Scripts\activate (така е посочено в документацията на Python). Внимание: курсът не е изпробван на Windows; ако някой изход не съвпада, сравни го с този в хранилището, преди да приемеш, че си сгрешил.

Ако получиш тази грешка: прескочил си стъпката по-горе. В Ubuntu 24.04 (същата основа като Linux Mint 22) съобщението изглежда така:

The virtual environment was not created successfully because ensurepip is not
available.  On Debian/Ubuntu systems, you need to install the python3-venv
package using the following command.

    apt install python3.12-venv

You may need to use sudo with that command.  After installing the python3-venv
package, recreate your virtual environment.

Обърни внимание, че съобщението предлага python3.12-venv, с номера на версията, а тук ние искаме python3-venv, без номер. И двата вършат работа: python3-venv инсталира отвътре този за твоята версия. Предпочитаме този без номер, защото продължава да работи, когато системата ти смени версията на Python. Изпълни sudo apt install python3-venv и пусни отново двата реда.

Внимание: всеки нов терминал започва със затворена среда. Изпълни отново source ~/tensores/bin/activate и потърси (tensores). Ако не го виждаш, Python няма да намери PyTorch.

Официалната команда

С активирана среда обнови инсталатора на пакети и след това инсталирай PyTorch с официалната команда от сайта му за Linux, без видеокарта:

pip3 install --upgrade pip
pip3 install torch==2.14.1 torchvision==0.29.1 --index-url https://download.pytorch.org/whl/cpu

Какво казва тази команда, част по част:

  • torch==2.14.1 е PyTorch, в точната версия, с която е написан този курс. Фиксираме я, за да съвпадат изходите ти с тези от урока: с друга версия числата може леко да се различават и няма да знаеш дали грешката е твоя.
  • torch е PyTorch. Името идва от Torch, по-ранна библиотека, написана на друг език (Lua), от чиято общност излиза част от хората, които го създават.
  • torchvision е придружаващ пакет за изображения. Включен е в официалната команда и не пречи.
  • --index-url https://download.pytorch.org/whl/cpu казва на pip от кой магазин да изтегли: този на изданието само за CPU. Без тази част в Linux ще ти изтегли изданието за видеокарти NVIDIA, което е много по-голямо и не ти трябва в този курс.

Изтеглянето е голямо; не бързай.

Проверка, че е инсталиран

Създай файл verifica.py в същата папка, в която е dimensiones.py:

import torch
print(torch.__version__, torch.cuda.is_available())

Изпълни го с python3 verifica.py:

2.14.1 False

Първата стойност е версията на PyTorch. Ако на теб ти излезе 2.14.1+cpu, и това е наред: +cpu е етикетът на изданието само за CPU. Втората стойност пита дали PyTorch може да използва видеокарта на NVIDIA (това, което PyTorch нарича CUDA). Тъй като си инсталирал изданието само за CPU, False е точно каквото очакваме, дори лаптопът ти да има видеокарта.

Какво е GPU? Това е видеокартата: създадена е, за да рисува милиони точки по екрана едновременно във видеоигрите. CPU е шепа много умели готвачи; GPU е екип от хиляди помощници, които знаят само да кълцат, но кълцат всички наведнъж, а умножаването на големи тензори е чисто кълцане. Целият курс работи на CPU на обикновен лаптоп.

Матео вижда False и се засмива. Доня Лупе, която не откъсва очи от екрана, пита дали това е лошо. — Значи, че PyTorch няма да използва видеокарта на лаптопа ми, лельо. — А, ами добре. Така ще учиш.


Стъпка 2 — От числото и списъка към тензора

8:25 вечерта. Файлът от Norte е на един клик от Матео. Не го отваря. Първо ще се упражни с данните от миналата седмица, за които вече знае, че са наред. Ако нещо се провали с добри данни, грешката е негова. Ако се провали с новите данни, грешката идва от данните. Смесването на двете е най-бързият начин да не разбереш нищо.

Днес има само една функция за научаване, за да създаваш тензори: torch.tensor. Даваш ѝ списъците си и тя ти връща тензор със същите числа.

Създай primer_tensor.py в същата папка като dimensiones.py. Редът from dimensiones import ... взема списъците, които написа миналата седмица, без да ги копираш отново:

import torch
from dimensiones import total, por_dia

t_total = torch.tensor(total)
t_dia = torch.tensor(por_dia)

print(t_total)
print(t_dia)
print(t_total.shape, t_dia.shape)

Изпълни го с python3 primer_tensor.py:

tensor(18500)
tensor([2500, 3100, 2200, 2800, 3900, 2400, 1600])
torch.Size([]) torch.Size([7])

Три неща, които да разчетеш в този изход:

  • PyTorch обвива числата ти в tensor(...): това вече не е списък на Python, а тензор.
  • Скаларът изглежда като tensor(18500), без скоби. Нула измерения, точно като в сесия 1.
  • .shape е формата. За скалара излиза torch.Size([]), празна, защото няма нито една посока. За седмицата излиза torch.Size([7]): седем дни.

Обърни внимание: .shape е без скоби. Не е функция, а стойност, която тензорът вече пази, като етикета с размера на риза: не го измерваш, прочиташ го.

— И какво от това? — казва доня Лупе и сочи 18500. — Същото е, което аз вече си имах записано. — Точно там е работата, лельо. Да е същото. Сега и компютърът го знае.


Стъпка 3 — Цялата книжарница

Сега таблицата с двата ѝ листа. Създай papeleria.py в същата папка; този файл ще пази тензора, който ще използваш в следващите сесии:

import torch
from dimensiones import centro, norte

papeleria = torch.tensor([centro, norte])

# Esto corre al abrir papeleria.py, no cuando otra sesión lo importa.
if __name__ == "__main__":
    print(papeleria)
    print(papeleria.shape)
    print(papeleria.ndim)
    print(papeleria.numel())
    print(papeleria.dtype)

Изход:

tensor([[[1200,  800,  500],
         [1500,  900,  700],
         [1000,  700,  500],
         [1300,  900,  600],
         [2000, 1200,  700],
         [1200,  800,  400],
         [ 800,  500,  300]],

        [[ 300,  200,  100],
         [ 400,  250,  150],
         [ 350,  200,  100],
         [ 300,  150,  100],
         [ 500,  300,  200],
         [ 300,  200,  100],
         [ 200,  100,  100]]])
torch.Size([2, 7, 3])
3
42
torch.int64

Условието if __name__ == "__main__": оставя тези пет проверки за случая, когато пускаш този файл директно. Следващите сесии ще могат да използват from papeleria import papeleria, без отново да отпечатват цялата таблица.

PyTorch подравнява колоните и оставя празен ред между листа Centro и листа Norte: същата таблица с листове от миналата седмица. Сега разчети четирите отговора:

Питаш го Пишеш Отговаря ти Означава
Каква форма имаш? papeleria.shape torch.Size([2, 7, 3]) 2 клона, 7 дни, 3 продукта
Колко измерения? papeleria.ndim 3 клон, ден и продукт
Колко числа съдържаш? papeleria.numel() 42 2 × 7 × 3
От какъв тип са? papeleria.dtype torch.int64 цели числа (виждаме го в стъпка 4)

Имената идват от английски: shape е „форма“; ndim — „брой измерения“; numel, number of elements, „брой елементи“; dtype, data type, „тип данни“. Обърни внимание на една подробност: numel() е със скоби, защото е функция, която брои. Другите три не са.

torch.Size([2, 7, 3]) е твоята forma от миналата седмица

Сесия 1 завърши с този изход от функцията ти:

papeleria 3 (2, 7, 3)

А днес PyTorch ти казва torch.Size([2, 7, 3]). Това е абсолютно същото, само облечено в други дрехи. torch.Size е начинът, по който PyTorch пази една форма, и отвътре се държи като кортеж. Затова можеш да я сравниш директно с (2, 7, 3).

Твоят while с append и .shape вършат една и съща работа. Разликата: тази на PyTorch, както ще видиш в стъпка 5, не се оставя да бъде излъгана от крив списък.

Проверка с assert: първо формата, после стойността

Не вярвай на никого, дори на PyTorch: провери го. Създай compara.py:

import torch
from dimensiones import centro, norte, forma, contar_dimensiones

papeleria_lista = [centro, norte]
papeleria = torch.tensor([centro, norte])

# 1) Primero la forma: PyTorch contra tus funciones de la sesión 1
print(papeleria.shape, forma(papeleria_lista))
print(papeleria.ndim, contar_dimensiones(papeleria_lista))
assert papeleria.shape == (2, 7, 3), "La papelería debería ser 2 sucursales × 7 días × 3 productos"
assert papeleria.shape == forma(papeleria_lista), "PyTorch y tu función deberían dar la misma forma"
assert papeleria.ndim == contar_dimensiones(papeleria_lista), "Deberían contar las mismas dimensiones"

# 2) Después el total de números, contra un for
cuenta = 0
for pestana in papeleria_lista:
    for renglon in pestana:
        for numero in renglon:
            cuenta = cuenta + 1
print(papeleria.numel(), cuenta)
assert papeleria.numel() == cuenta, "Deberían ser los mismos números"

# 3) Al final, el valor: de regreso a listas, ¿quedó igual?
assert papeleria.tolist() == papeleria_lista, "Los datos no deberían cambiar al convertirlos"
print("Todo cuadra")

Изход:

torch.Size([2, 7, 3]) (2, 7, 3)
3 3
42 42
Todo cuadra

Три проверки, в този ред:

  1. Формата. Това е assert, който ще пишеш във всяко упражнение от курса. Ако формата е грешна, всичко останало е грешно.
  2. Общият брой срещу един for. Трите вложени for броят едно по едно онова, което numel() брои с една дума. Ако и двете дадат 42, нищо не се е изгубило и нищо не е в повече.
  3. Стойността. .tolist() прави обратния път: превръща тензора отново в списъци. Списъкът се казва papeleria_lista, за да не се сблъска с тензора papeleria; ако са еднакви, числата не са се променили по пътя.

Ако смениш (2, 7, 3) с (7, 2, 3), първият assert хвърля грешка със своето съобщение, както в сесия 1. Редът има значение: 2 листа по 7 реда не са същото като 7 листа по 2.

„Todo cuadra“ — всичко се връзва. Матео го прочита два пъти. С познатите данни инструментът не греши и не го оставя да сгреши. Вече може да му има доверие. Остава едно нещо преди файла от Norte: да разбере какви числа ще пази.


Стъпка 4 — Типът на числата: dtype

Всички числа в един тензор са от един и същи тип. Не е позволено да смесваш, както в списък на Python, цяло число с текст. Този единствен тип се нарича dtype.

Защо? Защото така компютърът знае точно колко място заема всяко число и ги нарежда в редица, без да ги проверява едно по едно, като еднакво големи кутии на рафт.

За начало ти стигат два типа:

dtype Какво пази Пример
torch.int64 цели числа: бройки, песо без сентаво, преброявания 12 тетрадки
torch.float32 числа с десетична част: измервания, средни стойности, проценти среден успех 9.7

Числото в името е колко място заема всяко от тях, в битове: 64 или 32. Засега не ти трябва повече.

Едно предупреждение за деня, в който работиш с истински пари: float32 пази десетичните числа приблизително (0.1 остава като 0.10000000149011612). За точни суми системите пазят сентавото като цели числа: $35.50 се пази като 3550. В примера по-долу използваме цени с десетична част само за да видим какъв dtype излиза.

Създай tipos.py:

import torch

piezas = torch.tensor([12, 30, 7])
precios = torch.tensor([35.5, 12.0, 450.0])
mezcla = torch.tensor([12, 30.5, 7])

print(piezas, piezas.dtype)
print(precios, precios.dtype)
print(mezcla, mezcla.dtype)

Изход:

tensor([12, 30,  7]) torch.int64
tensor([ 35.5000,  12.0000, 450.0000]) torch.float32
tensor([12.0000, 30.5000,  7.0000]) torch.float32

Правилото, което PyTorch следва:

  • Ако всички са цели, излиза int64. Затова книжарницата ти излезе torch.int64: доня Лупе записва песо без сентаво.
  • Ако поне едно има десетична точка, излиза float32, и целите също стават десетични: 12 се превръща в 12.0000. Стига едно-единствено 30.5, за да се промени цялата редица.

— Аз не записвам сентаво — казва доня Лупе. — Сентавото е работа на банката. — Затова таблицата ти излезе int64, лельо. Цели числа, като теб. — Да не искаш да кажеш, че съм дървена? — Искам да кажа, че си точна.

Сам да избереш типа

Понякога искаш десетични числа, макар данните ти да са цели. Например, за да изчисляваш средни стойности, както ще видиш в сесия 4. За целта torch.tensor приема втори аргумент:

import torch
from dimensiones import por_dia

dia_dec = torch.tensor(por_dia, dtype=torch.float32)
print(dia_dec)
print(dia_dec.dtype)

Изход:

tensor([2500., 3100., 2200., 2800., 3900., 2400., 1600.])
torch.float32

Точката след всяко число (2500.) е знакът, че вече са десетични. Същите числа, друг тип.


Стъпка 5 — Кривият списък: PyTorch казва „не“

10:15 вечерта. Сега вече да. Матео копира седемте реда от файла на Norte в списък, пише обичайния ред, torch.tensor(...), и натиска Enter.

Терминалът се изпълва с червени букви.

— Да не си го развалил? — пита доня Лупе.

— Не, лельо. Отказа.

Матео слиза по файла, ред по ред, с пръст върху екрана. Понеделник: три числа. Вторник: две. Сряда: три. На вторника му липсва едно.

Преди да прави изводи, той го възпроизвежда в малък мащаб. В сесия 1 видя, че функцията ти forma се оставяше да бъде излъгана от този списък и трябваше да го проверяваш с es_rectangular:

chueca = [[1, 2, 3], [4, 5]]

Да го дадем на PyTorch. Създай chueca.py:

import torch

chueca = [[1, 2, 3], [4, 5]]
t = torch.tensor(chueca)

Изпълни го:

Traceback (most recent call last):
  File ".../chueca.py", line 4, in <module>
    t = torch.tensor(chueca)
        ^^^^^^^^^^^^^^^^^^^^
ValueError: expected sequence of length 3 at dim 1 (got 2)

Същото червено като с файла от Norte. PyTorch отказва да създаде тензора. Важното е последният ред и той се разчита дума по дума:

Казва Преведено Какво означава тук
ValueError грешка в стойността стойността, която си му дал, не става за това
expected sequence of length 3 очаквах списък с дължина 3 първият ред беше с дължина 3, така че всички трябва да са с дължина 3
at dim 1 в измерение 1 вътрешното измерение: редовете. Външното е 0
(got 2) получих 2 намери ред с дължина 2

Обърни внимание на dim 1. Измеренията се номерират от 0, точно като индексите на списък: външното е 0, следващото е 1. В книжарницата измерение 0 са клоновете, 1 — дните, а 2 — продуктите. Тази номерация ще я използваш много в сесия 3.

Това е твоята es_rectangular, но по-добра: проверява всички кутии на всички нива и ти казва къде е проблемът. Затова тензорът, който създаваш с torch.tensor, винаги е правоъгълен. (PyTorch има специални тензори за неравномерни данни, но в този курс не ги използваме.)

Функцията ти от миналата седмица щеше да погълне файла от Norte, без да каже нищо. PyTorch — не: предпочита да хвърли грешка, отколкото да те излъже.

Как се оправя: не като се допълни с измислено число. Матео би могъл да сложи нула във вторника и да продължи. Тензорът би излязъл перфектен и би лъгал: нулата казва „нищо не е продадено“; празното място казва „не знам“. Не е същото. Попитай този, който ти е дал данните, кое липсва. Ако липсват раниците от вторника, тензорът не се оправя с нула; оправя се с въпрос.

— Кой съставя този файл, лельо? — Изпраща го клонът. Всеки понеделник. Никога не е пристигал сгрешен. Никога. Матео остава загледан във вторника.


Каре: битката на двама гиганти (PyTorch и TensorFlow)

Докато PyTorch се изтегляше, Матео си зададе въпрос: щом този инструмент е толкова добър, защо навсякъде чува друго име? Ще чуваш две имена непрекъснато, а зад тях има битка между двама гиганти. Данните са от проучването за курса, с дата.

Който дойде пръв. TensorFlow е на Google. Пусна го с отворен код на 9 ноември 2015 г., с разрешение всеки да го използва: точно единадесет години преди вечерта, в която Матео инсталира съперника му. Актуалната версия към октомври 2026 г. е 2.21.0, публикувана на 6 март 2026 г.

Претендентът. PyTorch се ражда във Facebook (днес Meta), в изследователската му лаборатория. Първите му версии в GitHub са от септември 2016 г., десет месеца по-късно, а официалното му пускане — от януари 2017 г. От септември 2022 г. вече не принадлежи на една-единствена компания: грижи се за него PyTorch Foundation, част от Linux Foundation, а негови членове основатели са AMD, AWS (на Amazon), Google Cloud, Meta, Microsoft Azure и NVIDIA. Обърни внимание на едно име в този списък: Google Cloud, от същата къща като съперника, също седи там. Актуалната версия, докато пишем тази сесия (октомври 2026 г.), е 2.14.1, публикувана на 30 септември 2026 г. Ако на теб ти се е инсталирала по-нова, няма проблем.

Кой печели? Зависи от ринга.

  • В моделите, които хората публикуват, PyTorch, с голяма преднина. В Hugging Face, сайтът, където хората публикуват модели на ИИ, на 18 октомври 2026 г. имаше 258,777 модела с етикета на PyTorch срещу 17,469 с този на TensorFlow: около 15 на всеки един. Това измерва какво качват хората, а не какво използват в работата си, но разликата е ясна. А най-популярната библиотека с модели в Hugging Face, Transformers, обяви, че във версия 5 изоставя TensorFlow и остава само с PyTorch.
  • Сред програмистите — почти равенство. В анкетата на Stack Overflow от 2024 г. 10.6 % от отговорилите казаха, че използват PyTorch, а 10.1 % — TensorFlow. Анкетата пита какво използва всеки, а не какво работи в продукция. TensorFlow стигна по-рано до компаниите и още е жив в много от тях, както и в мобилните телефони.

Източници: обявлението на Google за TensorFlow (2015); версии в PyPI: tensorflow и torch; версии на PyTorch в GitHub; Linux Foundation, 12 септември 2022 г.; модели на PyTorch в Hugging Face, справка от 18 октомври 2026 г. (цифрата се променя всеки ден); анкета на Stack Overflow 2024.

Една разлика, която ще забележиш, ако някой ден използваш и двата: със същите цели числа PyTorch създава int64, а TensorFlow — int32.

PyTorch TensorFlow
Създаване на тензор torch.tensor([1, 2, 3]) tf.constant([1, 2, 3])
Цяло число по подразбиране int64 int32
С десетична част float32 float32

Кой да използвам? За учене и за четене на изследователски код — PyTorch. Ако някой ден в работата ти използват TensorFlow, ще го научиш за един следобед: формата, измеренията и типът работят по същия начин.


👉 Ако идваш от бизнес администрацията: dtype е форматът, който даваш на колона в електронната си таблица: „цяло число“ или „валута с два знака след десетичната запетая“. А грешката с кривия списък е отчетът на клона, който пристига с една колона по-малко: не се сумира с останалите, докато някой не попита какво липсва. Когато анализатор ти каже „моделът не тръгна, защото данните нямаха правилната форма“, вече знаеш за какво говори.


Упражнения към сесия 2

Решенията са в края на тази публикация. Работи в същата папка като dimensiones.py и с активирана среда.

Упражнение 6 — Предвиди, преди да изпълниш. Напиши на хартия формата, измеренията, типа и общия брой числа на всеки тензор. После изпълни и сравни.

import torch

temperatura = torch.tensor(31)
calificaciones = torch.tensor([[9, 8, 10], [7, 9, 8], [10, 10, 9], [6, 8, 7]])
foto = torch.tensor([[[255, 0, 0], [0, 255, 0]], [[0, 0, 255], [255, 255, 255]]])
promedios = torch.tensor([9.0, 8.0, 9.7, 7.0])

for nombre, t in [("temperatura", temperatura), ("calificaciones", calificaciones),
                  ("foto", foto), ("promedios", promedios)]:
    print(nombre, t.shape, t.ndim, t.dtype, t.numel())

Това са същите данни като в упражнение 1 от сесия 1, плюс едни с десетична част. Подсказка: колко числа съдържа един скалар?

Упражнение 7 — Попълни празните места. Само листът Norte, като тензор. Попълни ____ и изпълни. Ако последният print се появи, познал си.

import torch
from dimensiones import norte

norte_t = torch.____(norte)

assert norte_t.shape == ____, "Norte es una pestaña: 7 días × 3 productos"
assert norte_t.ndim == ____, "Una pestaña es una tabla"
assert norte_t.numel() == ____, "7 × 3"
assert norte_t.dtype == ____, "Son pesos enteros"
assert norte_t.tolist() == norte, "Los datos no deberían cambiar"
print("Ejercicio 7 superado")

Упражнение 8 — Твоите собствени данни, вече като тензор. Вземи оценките, които написа в упражнение 4 от сесия 1 (ученици, предмети и контролни), и:

а) Превърни ги в тензор и напиши assert за формата им срещу функцията си forma. б) Напиши assert за измеренията им срещу contar_dimensiones. в) Преброй числата им с вложени for и ги сравни с assert срещу numel(). г) Създай втора версия с dtype=torch.float32 и провери с assert, че типът се е променил, но формата — не.

Завърши с print("Ejercicio 8 superado").

Упражнение 9 — Намери кривия, вече с PyTorch. Преди да изпълниш, предвиди кои ще хвърлят грешка и какъв номер на dim ще каже грешката. После изпробвай всеки поотделно с torch.tensor(...).

a = [[1, 2], [3, 4], [5, 6]]
b = [[1, 2, 3], [4, 5, 6], [7, 8]]
c = [[[1, 2], [3, 4]], [[5, 6], [7]]]
d = [[1, 2], [3, 4, 5]]

За тези, които хвърлят грешка, отговори: защо при d грешката казва, че е очаквала 2 и е получила 3, щом редът, който е „в повече“, е вторият? И оправи b, като добавиш числото, което му липсва (приеми, че е 9).


Чести грешки (и как да ги забележиш)

Грешка Как изглежда Как да я забележиш Какво да направиш
Забравена активация на средата ModuleNotFoundError: No module named 'torch' Терминалът ти не започва с (tensores) Изпълни source ~/tensores/bin/activate във всеки нов терминал
Файлът ти се казва torch.py AttributeError: partially initialized module 'torch' has no attribute 'tensor' (most likely due to a circular import) Хвърля грешка на първия ред, който използва torch. Python е импортирал твоя файл вместо PyTorch. Преименувай го, например на primer_tensor.py
Скоби след .shape TypeError: 'torch.Size' object is not callable Написал си t.shape() .shape, .ndim и .dtype са без скоби; само .numel() има
Забравени скоби на numel Излиза нещо като <built-in method numel of Tensor object at 0x...> вместо число print не показва число Пиши t.numel(), със скоби
torch.Tensor с главна буква torch.Tensor([1, 2, 3]) дава tensor([1., 2., 3.]), десетични dtype излиза torch.float32 при цели данни Използвай torch.tensor, с малка буква: запазва типа на данните ти

Преговор за следващата сесия

Сесия 3 започва с тези три въпроса. Отговори на тях, без да поглеждаш урока:

  1. Какво ти казва t.shape и как го проверяваш с assert?
  2. Защо torch.tensor([[1, 2, 3], [4, 5]]) се проваля?
  3. Какъв dtype излиза от torch.tensor([1, 2, 3]) и какъв от torch.tensor([1.0, 2.0])?

🔁 Следващата седмица: книжарницата вече е тензор. Сега ще изваждаш части от нея по която и да е от осите ѝ: само листа Norte, само петъците на двата клона, само раниците за цялата седмица. И ще видиш, че една снимка се изрязва точно по същия начин.

Минава единадесет, когато Матео затваря лаптопа. Доня Лупе вече е преброила касата и чака до ролетката с ключовете в ръка. В телефона още е отворен файлът от Norte, с неговия вторник от две числа. Не прилича на обикновена грешка при писане: това е единственият крив ред в седмици прави файлове. И пристигна точно седмицата, в която банката спря терминала.

Кой оставя един ден наполовина?


Решения (не ги гледай, преди да опиташ)

Преговор за начало.

  1. Броиш колко сведения ти трябват, за да посочиш едно-единствено число. В книжарницата ти трябват клонът, денят и продуктът: три сведения, три измерения. А ако не искаш да броиш сам, брои ги contar_dimensiones (и от днес — .ndim).
  2. Че има 2 елемента в първото измерение (клонове), 7 във второто (дни) и 3 в третото (продукти). Общо 2 × 7 × 3 = 42 числа.
  3. Да е правоъгълен: всички кутии на едно и също ниво трябва да са с еднакъв размер. Всички листове със 7 реда, всички редове с 3 колони.

Упражнение 6.

temperatura torch.Size([]) 0 torch.int64 1
calificaciones torch.Size([4, 3]) 2 torch.int64 12
foto torch.Size([2, 2, 3]) 3 torch.int64 12
promedios torch.Size([4]) 1 torch.float32 4

Капанът беше скаларът: формата му е празна и има нула измерения, но съдържа едно число. promedios излиза float32, защото има десетична част. Обърни внимание и че calificaciones и foto съдържат едни и същи 12 числа с различни форми: общият брой не ти казва формата, но формата ти казва общия брой.

Упражнение 7.

norte_t = torch.tensor(norte)

assert norte_t.shape == (7, 3), "Norte es una pestaña: 7 días × 3 productos"
assert norte_t.ndim == 2, "Una pestaña es una tabla"
assert norte_t.numel() == 21, "7 × 3"
assert norte_t.dtype == torch.int64, "Son pesos enteros"

Изход:

Ejercicio 7 superado

Упражнение 8. Един възможен отговор, със списъка parciales (ученик × предмет × контролна) от решението на упражнение 4 от сесия 1:

import torch
from dimensiones import forma, contar_dimensiones

# alumno × materia × parcial
parciales = [
    [[8, 9, 9], [7, 8, 9], [9, 9, 10], [6, 7, 8]],
    [[10, 9, 10], [9, 9, 9], [8, 8, 9], [9, 10, 10]],
    [[7, 7, 8], [8, 8, 8], [6, 7, 7], [8, 9, 9]],
]

p = torch.tensor(parciales)
print(p.shape, p.ndim, p.numel(), p.dtype)
assert p.shape == forma(parciales), "PyTorch y tu función deberían coincidir"
assert p.ndim == contar_dimensiones(parciales)

cuenta = 0
for alumno in parciales:
    for materia in alumno:
        for calificacion in materia:
            cuenta = cuenta + 1
assert p.numel() == cuenta

p_dec = torch.tensor(parciales, dtype=torch.float32)
print(p_dec.dtype)
assert p_dec.dtype == torch.float32
assert p_dec.shape == p.shape, "Cambiar el dtype no cambia la forma"
print("Ejercicio 8 superado")

Изход:

torch.Size([3, 4, 3]) 3 36 torch.int64
torch.float32
Ejercicio 8 superado

Ако данните ти са в друг ред или с други размери, формата ти ще е различна, и това е наред: важното е редовете assert да минават.

Упражнение 9.

  • a работи: torch.Size([3, 2]).
  • b хвърля грешка: ValueError: expected sequence of length 3 at dim 1 (got 2). Последният ред е с дължина 2, а останалите — 3.
  • c хвърля грешка: ValueError: expected sequence of length 2 at dim 2 (got 1). Тук проблемът е по-навътре, в измерение 2: последната двойка, [7], съдържа само едно число.
  • d хвърля грешка: ValueError: expected sequence of length 2 at dim 1 (got 3). PyTorch приема първия ред за правило. Първият е с дължина 2, така че вторият, с дължина 3, е този, който „е сгрешен“, макар на теб да ти се струва, че на първия му липсва едно. Затова грешката ти казва къде е нарушено правилото, но да решиш коя стойност е вярната, е твоя работа, заедно с този, който ти е дал данните.

b, оправен:

b = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(torch.tensor(b).shape)
torch.Size([3, 3])

Какво следва

В сесия 3 спираш да гледаш целия тензор и започваш да изваждаш части от него. Ако искаш да напреднеш, отвори своя papeleria.py и подготви тензора papeleria: това е първото, което ще използваш.


Пиша от онова, което виждаме всеки ден в Hábil, където изграждаме системи за банки, застрахователи и компании в Мексико. Ако в работата ти или в семейния ти бизнес се сблъскаш с подобен проблем, нека поговорим: habil.mx

Да обсъдим вашия проект

Предпочитате имейл? Пишете ни на hola@habil.mx