-
Agora que você já sabe o que é
um modelo de IA generativa,
-
nós vamos dar um mergulho
mais profundo e começar a ver
-
como podemos implementar
esses modelos na prática.
-
Para isso, precisamos conhecer
a base desses modelos.
-
A base para modelos
de IA generativa
-
são redes neurais
artificiais,
-
e a base para redes neurais
artificiais é álgebra linear.
-
Então, nesse laboratório, veremos
uma revisão sobre álgebra linear
-
utilizando a biblioteca
NumPy do Python.
-
Álgebra linear, basicamente, é
como podemos fazer operações
-
com vetores e matrizes.
-
Então, para começar
esse laboratório,
-
a gente vai começar a relembrar
um pouco sobre vetores
-
e ver como podemos representar
esses vetores no Python.
-
Para isso, a gente vai utilizar
a biblioteca NumPy do Python.
-
Essa biblioteca é especializada
em cálculo numérico e álgebra linear,
-
então é a principal biblioteca
do Python para esse fim.
-
Então, vamos começar o nosso
código importando essa biblioteca
-
para dentro do código.
-
Então, "import numpy as np".
-
Bom, para definir
um vetor no NumPy,
-
eu posso utilizar o módulo
"array" do NumPy.
-
Então, se eu criar
um "vetor_a = np.array"
-
e passar uma lista
de valores para ele,
-
ele vai criar
um vetor para mim.
-
Se eu quiser criar
um segundo vetor, "b",
-
eu também posso
utilizar o mesmo código.
-
Então, "np.array", vou passar
uma lista de valores
-
e será criado um array, ou um vetor,
e associado à variável "vetor_b".
-
Nesse código aqui, vamos
criar dois vetores, "A" e "B",
-
e vamos printar
esses vetores.
-
Então, aqui nas respostas,
vetor A e vetor B,
-
da forma como a gente
criou anteriormente,
-
e as dimensões do vetor A,
-
por exemplo, o vetor B tem
a mesma dimensão do vetor A.
-
Então, o que é a dimensão
de um vetor?
-
São quantos elementos
tem nesse vetor.
-
Então, esse vetor tem
três elementos, perfeito?
-
Se eu quiser fazer a soma
desses dois vetores,
-
eu posso simplesmente vir aqui
e criar uma variável "soma_vetores",
-
que vai ser igual
a "vetor_a + vetor_b".
-
E, aqui, eu vou printar
a soma desses vetores.
-
Então, quando nós somamos dois
vetores, qual operação é feita?
-
Basicamente, uma soma,
elemento a elemento,
-
então cada elemento
do vetor A
-
vai ser somado com o mesmo
elemento do vetor B,
-
e eu vou ter esse
resultado aqui na soma.
-
Se eu quiser fazer uma subtração,
da mesma forma, "vetor_a - vetor_b",
-
e o resultado é uma subtração
elemento a elemento.
-
Então, eu posso, por exemplo, criar
uma variável "vetor_multiplicado",
-
que vai ser igual ao vetor_a vezes
um valor escalar, por exemplo, "2".
-
Essa multiplicação também
será feita elemento a elemento,
-
então cada elemento do vetor A
será multiplicado por 2,
-
e aqui a gente tem,
no nosso código,
-
a resposta desse
vetor multiplicado.
-
Então, 1 vezes 2,
2 vezes 2, 3 vezes 2,
-
e a resposta aqui na variável
"vetor_multiplicado".
-
Uma outra operação
muito importante,
-
que eu posso fazer
com dois vetores,
-
se chama "produto escalar".
-
O produto escalar
entre dois vetores
-
é uma operação onde eu vou
multiplicar esses dois vetores
-
e o resultado será
um número escalar.
-
O que esse número
representa?
-
Esse número representa
um certo grau de similaridade
-
entre esses dois
vetores, ou seja,
-
se esses vetores
estiverem apontando
-
para uma mesma direção,
esse produto será maior.
-
Se esses produtos estiverem
perpendiculares um com o outro,
-
ou seja, se tiver um ângulo
de 90 graus entre eles,
-
esse produto escalar vai
retornar algo próximo de 0.
-
E se eles estiverem apontando
para direções opostas,
-
isso significa que esse produto
escalar terá um valor negativo.
-
Então, basicamente,
o produto escalar
-
é uma forma de você
multiplicar dois vetores
-
e obter um escalar
como resposta,
-
e esse escalar tem
um certo significado,
-
indica, mais ou menos,
se esses dois vetores
-
estão apontando
para direções parecidas.
-
Como eu calculo isso?
-
Por trás dos panos,
eu estou fazendo
-
linhas de um vetor
versus colunas do outro.
-
Então, se for necessário,
por exemplo, nesse caso,
-
a gente tem vetores
de mesmas dimensões,
-
o segundo vetor vai ser
transposto, nesse caso.
-
Então, se eu fizer, aqui, o produto
escalar do vetor A com o vetor B,
-
eu vou ter um número, 32.
-
Esse número indica,
de certa forma,
-
se esses dois vetores
estão apontando
-
para direções similares
ou opostas.
-
Outro conceito
muito importante
-
quando a gente fala
de álgebra linear
-
é o conceito de matrizes.
-
Então, diferentemente dos vetores,
que têm apenas uma dimensão,
-
as matrizes podem ter
duas dimensões.
-
Então, as matrizes vão
ter linhas e colunas.
-
Então, serão parecidas
com uma tabelinha,
-
que teria linhas e colunas.
-
Então, eu posso criar, aqui
no Python, uma matriz X,
-
usando o "np.array",
-
e, em vez de passar apenas
uma lista de valores,
-
eu vou passar uma lista
de listas de valores,
-
onde cada lista vai representar
uma linha dessa matriz.
-
Essa matriz tem duas linhas,
essa linha e essa linha,
-
e duas colunas, essa
coluna e essa coluna.
-
Então, é uma matriz que tem
dimensões 2 por 2.
-
A matriz Y também é
uma matriz 2 por 2,
-
porque ela tem duas
linhas e duas colunas.
-
Se a gente rodar esse código,
a gente vai ver essas duas matrizes
-
dispostas, aqui, da forma
que a gente criou elas, perfeito?
-
As operações que a gente
pode fazer com as matrizes
-
são muito similares às operações
que a gente pode fazer
-
com os vetores.
-
Então, eu posso olhar
para o shape dessa matriz,
-
vai me dar
as dimensões dela,
-
então quais são
as dimensões dessa matriz?
-
No vetor, a gente tinha
apenas uma dimensão,
-
então a gente criou
um vetor de três posições.
-
Aqui, eu tenho duas dimensões,
eu tenho linhas e colunas,
-
então cada uma das nossas matrizes
tem duas linhas e duas colunas.
-
Isso, a gente consegue saber usando
o atributo "shape" da nossa matriz.
-
Da mesma forma
como vetores,
-
como a gente fez
para os nossos vetores,
-
a gente pode somar matrizes.
-
Então, quando eu somo
a matriz X com a matriz Y,
-
eu estou fazendo a mesma operação
que a gente fez para os vetores,
-
então eu estou somando,
elemento a elemento,
-
os valores das duas matrizes.
-
Então, se a gente fizer
a soma e printar essa soma,
-
a gente vai ter o resultado,
que é a soma das duas matrizes,
-
elemento a elemento.
-
Da mesma forma,
-
se a gente fizer a subtração
entre essas duas matrizes,
-
eu também vou ter o resultado
-
como sendo uma matriz resultante
de mesma dimensão, 2 por 2,
-
onde cada valor é a subtração,
elemento a elemento,
-
dessas duas matrizes.
-
Por fim, eu posso multiplicar
essa matriz, ou alguma matriz,
-
por um valor escalar,
-
e aí, eu também terei uma resposta
-
que vai ser a multiplicação desse
escalar, por exemplo, o valor "3",
-
por cada elemento
dessa matriz.
-
Então, o resultado também
é uma matriz 2 por 2,
-
e essa matriz 2 por 2,
cada elemento dela
-
é o resultado da multiplicação
desse escalar pelo valor da matriz.
-
Da mesma forma que fizemos
o produto escalar para vetores,
-
podemos, também,
aplicar para matrizes,
-
porém, com uma pequena
diferença.
-
Nos vetores, temos
apenas uma dimensão,
-
nas matrizes, a gente
tem duas dimensões.
-
Então, se eu criar
uma matriz, por exemplo,
-
chamada "matriz_a_mult",
-
como uma matriz que vai ter
duas linhas e três colunas,
-
eu utilizaria esse código
aqui para criá-la.
-
Poderia criar, também,
uma "matriz_b_mult",
-
essa matriz em vez de ter
duas linhas por três colunas,
-
vai ter três linhas
por duas colunas.
-
Então, se a gente rodar
esse código aqui,
-
a gente pode ver, aqui,
as nossas duas matrizes.
-
Uma tem dimensões 2 por 3,
uma tem dimensões 3 por 2.
-
Para fazer o produto escalar
dessas duas matrizes,
-
eu posso utilizar o mesmo
código do NumPy,
-
a mesma função,
o mesmo método,
-
"np.dot", "matriz_a_mult"
e "matriz_b_mult",
-
e eu vou ter o resultado
dessa multiplicação.
-
Note que o resultado
dessa multiplicação
-
é uma matriz de 2 por 2.
-
Então, existe uma regrinha
-
para a gente fazer multiplicação
matricial através do produto escalar
-
e essa multiplicação
ser possível.
-
Qual seria essa regra?
-
As dimensões da minha matriz A,
a quantidade de colunas dela
-
tem que ser igual à quantidade
de linhas da matriz B.
-
Então, sempre que eu estiver
fazendo o produto escalar
-
entre duas matrizes,
-
a quantidade
de colunas da primeira
-
tem que ser igual à quantidade
de linhas da segunda.
-
E o resultado sempre será
a quantidade de linhas da primeira
-
por a quantidade
de colunas da segunda.
-
Então, essas duas matrizes,
eu posso multiplicar, por quê?
-
Porque elas obedecem
o primeiro quesito,
-
a quantidade de colunas
da matriz A
-
é igual à quantidade
de linhas da matriz B.
-
E o resultado dessa conta
desse produto escalar
-
vai dar a quantidade
de linhas da matriz A
-
pela quantidade de colunas
da matriz B, que vai dar 2 por 2.
-
Então, se a gente pudesse
fixar um pouco essa regra,
-
você poderia pensar assim:
-
quando eu for multiplicar
duas matrizes,
-
fazer o produto escalar delas,
os valores de dentro, ou seja,
-
a quantidade de colunas da primeira
e de linhas da segunda
-
tem que ser igual,
-
e o resultado vai dar
os dois de fora, ou seja,
-
a quantidade de linhas
da primeira
-
e a quantidade
de colunas da segunda.
-
Então, seguindo aqui,
vamos passar, agora,
-
por outras operações relevantes
no nosso contexto de álgebra linear.
-
Um conceito mega importante,
uma operação mega importante
-
é inverter uma matriz.
-
Para inverter uma matriz, qualquer
matriz tem que ser quadrada,
-
como a que a gente
está criando aqui,
-
"matriz_quadrada = np.array",
uma matriz de 2 por 2.
-
Então, o que é
uma matriz quadrada?
-
Mesma quantidade de linhas é
a mesma quantidade de colunas.
-
E ela precisa ser não singular.
-
Ser não singular significa que
o determinante dela não pode ser 0.
-
Então, basicamente, inverter
uma matriz, no Python,
-
a gente pode fazer utilizando
o módulo do NumPy de linear algebra,
-
então "np.linalg",
-
e do linalg, eu vou usar
o método "inv", de inverter.
-
Então, vou criar uma variável
matriz inversa
-
e vou atribuir
para ela a inversa,
-
o cálculo da inversa dessa matriz
quadrada que a gente criou.
-
Quando a gente inverte
uma matriz, o que significa?
-
É como se eu estivesse
fazendo um cálculo análogo
-
a "1" sobre um determinado
número, esse é o inverso dela.
-
Então, "1" sobre essa matriz
é a mesma coisa
-
que a inversa
dessa matriz, perfeito?
-
Então, se a gente
rodar esse código,
-
a gente vai ver, aqui, a matriz
quadrada que a gente tinha criado
-
e aqui é a inversa
dessa matriz quadrada.
-
Ela é uma matriz quadrada,
então ela pode ser invertível
-
e ela é não singular, então ela
pode ser invertível também,
-
tem que obedecer esses
dois critérios aí, perfeito?
-
E aí, a gente pode,
depois, no nosso código
-
verificar essa inversão
dessa matriz.
-
Como eu poderia
fazer isso?
-
Se eu fizer o produto escalar
da matriz original com a sua inversa,
-
eu tenho que ter como resultado
a matriz identidade, ou seja,
-
a matriz identidade
no contexto de álgebra
-
é como se fosse o valor 1.
-
Então, é como se eu multiplicasse
a matriz por "1" sobre a matriz,
-
eu vou ter "1" como resposta, é isso
que quer dizer esse código aqui.
-
Seguindo no nosso código,
-
como a gente falou
de determinante da matriz,
-
a gente pode verificar, aqui,
-
como calcular o determinante
de uma matriz.
-
Então, vou criar,
aqui, uma matriz
-
para a gente calcular
o determinante com base nela
-
e eu vou utilizar o mesmo módulo
de linear algebra do NumPy,
-
só que eu vou usar, agora,
o método "det", de determinante.
-
Então, qual é o determinante
dessa matriz?
-
Se a gente rodar
esse código,
-
a gente vai ver que o determinante
dessa matriz é "4.99".
-
Se eu tiver
uma matriz singular,
-
o que significa
uma matriz singular?
-
Significa que é uma matriz
cujo determinante é 0.
-
Se o determinante dela é 0, eu
não consigo inverter essa matriz.
-
Então, essa matriz
singular que a gente criou
-
mais embaixo do nosso código é
uma matriz que não teria inversa,
-
não seria possível calcular
a inversa dessa matriz, perfeito?
-
Outra operação extremamente
importante é a norma de um vetor.
-
Então, a norma de um vetor
é como a gente calcula,
-
de certa forma,
o tamanho desse vetor.
-
Então, a norma desse vetor...
-
Existem várias formas de se
calcular a norma de um vetor.
-
A mais conhecida e a mais
utilizada é a norma L2,
-
que é também conhecida
como a norma Euclidiana.
-
Então, ela é dada
por essa continha aqui,
-
então vai ser a raiz quadrada
da soma dos valores dessa matriz,
-
desse vetor, ao quadrado,
-
então a raiz quadrada da soma
-
dos quadrados dos valores
dessa matriz, perfeito?
-
Então, se a gente tiver
uma matriz 3 e -4,
-
a norma Euclidiana
dessa matriz vai ser 5.
-
Como eu chego
nesse cálculo?
-
Fazendo a raiz quadrada
da soma dos quadrados
-
dos valores desse
vetor, perfeito?
-
Bom, então, para calcular
a norma Euclidiana,
-
eu posso usar o módulo
de álgebra linear do NumPy,
-
utilizando o método
"norm", certo?
-
E eu vou ter a norma
Euclidiana.
-
Existem, também, outras formas
de normas que a gente pode utilizar,
-
por exemplo, a norma
de Frobenius.
-
Não é uma norma
muito utilizada,
-
mas apenas para a gente conseguir
visualizar que existe um parâmetro,
-
eu posso parametrizar o tipo
de norma que eu quero
-
na função, no método
"norm" do NumPy.
-
Então, por padrão, essa biblioteca
já utiliza a norma Euclidiana,
-
mas eu poderia definir outra
dentre as normas possíveis,
-
e, para saber
as normas possíveis,
-
a gente pode olhar na documentação
dessa biblioteca, perfeito?
-
Outro cálculo muito interessante,
muito importante para criar IAs
-
e para a álgebra linear
como um todo,
-
é você calcular
distâncias entre vetores.
-
Então, eu posso
ter dois vetores
-
e eu quero calcular o quão
distantes esses vetores são.
-
Para fazer a distância
entre vetores,
-
eu posso, simplesmente,
calcular a diferença entre eles.
-
Então, se eu calcular
a diferença entre eles,
-
eu vou ter um
menos o outro,
-
eu vou ter a distância de cada
vetor em cada dimensão.
-
Quando eu quero criar, utilizar
uma distância Euclidiana,
-
o que é a distância Euclidiana?
-
É uma distância baseada
na norma Euclidiana,
-
então vai ser a norma L2,
-
a norma Euclidiana da diferença
entre os dois vetores,
-
então eu vou fazer a raiz quadrada
das diferenças elevada ao quadrado,
-
essa que é a conta.
-
No Python, eu poderia,
simplesmente, fazer a norma
-
das diferenças dos vetores
que a gente calculou aqui.
-
E, aqui, eu coloco a ordem 2,
a ordem já é presumida que é o 2,
-
por default,
-
e aí, a gente tem, aqui,
-
o que a gente chama de distância
Euclidiana entre dois vetores,
-
o quão distantes esses
dois vetores estão, certo?
-
Outra métrica bastante interessante
para se calcular entre dois vetores
-
é a distância de Manhattan.
-
Então, a única diferença
entre a distância Euclidiana
-
e a distância de Manhattan
é a ordem dessa norma.
-
Então, uma a gente
chama de norma L2,
-
a distância Euclidiana,
-
a distância de Manhattan,
a gente chama de L1,
-
tudo por causa da norma,
da ordem da norma.
-
O que isso muda
na prática?
-
Na norma Euclidiana,
-
isso muda que a gente usa
o quadrado das diferenças.
-
Na norma de Manhattan,
na distância de Manhattan,
-
norma L1, a gente
usa o módulo,
-
como se estivesse
usando uma ordem 1,
-
elevado a 1, esse número, então
a gente usa a norma dos valores.
-
Então, se a gente verificar aqui,
a gente vai ter diferentes normas
-
e cada norma dessa vai ser
mais útil ou menos útil
-
dependendo do caso
de uso que a gente tiver.
-
Outras operações úteis aqui
no contexto de álgebra linear:
-
a gente pode transpor uma matriz,
então, frequentemente,
-
a gente vai ter que calcular
a transposta de uma matriz.
-
O que é a transposta
de uma matriz?
-
É simplesmente eu transformar
o que era linha em coluna
-
e o que era coluna em linha.
-
Então, se eu criar uma matriz
3 por 2 com esses valores,
-
com esses elementos,
-
a transposta dessa matriz
original vai ser, simplesmente,
-
essa matriz transposta, ou seja,
linhas vão virar colunas
-
e colunas vão virar linhas,
-
então, no final,
a dimensão dessa matriz
-
vai de 3 por 2
para 2 por 3.
-
Então, vamos rodar
esse código para visualizar.
-
Eu tinha uma matriz
original 3 por 2,
-
a matriz transposta
vai ser 2 por 3.
-
Outro conceito interessante é
você criar uma matriz identidade.
-
Então, a matriz identidade é
uma matriz similar a um número 1,
-
então aquela matriz que, se você
multiplicar uma matriz por ela,
-
é como se você estivesse
multiplicando um número por 1,
-
então vai dar ela mesma.
-
Então, a matriz identidade
no Python, utilizando o NumPy,
-
a gente usa a função "eye".
-
Se eu colocar aqui,
como entrada, 2,
-
eu vou ter uma matriz
identidade 2 por 2,
-
se eu colocar 3, eu vou ter
uma matriz identidade 3 por 3.
-
Então, matriz identidade sempre
são matrizes quadradas, ou seja,
-
mesmo número
de linhas e de colunas.
-
Então, se a gente rodar aqui,
-
a gente vai ter a matriz
identidade, ela é 2 por 2,
-
vou ter a matriz transposta,
-
e, se eu multiplicar uma matriz
por sua identidade,
-
se eu fizer o produto
escalar entre eles,
-
eu vou ter como resultado
a mesma matriz original, certo?
-
Olha, "[1. 2.] [3. 4.]", resposta
"[1. 2.] [3. 4.]", perfeito?
-
Agora, algumas funções auxiliares
que o NumPy oferece para a gente:
-
então o NumPy oferece,
por exemplo,
-
uma funçãozinha
que é interessante
-
para o que a gente vai
fazer durante as aulas,
-
que se chama "linspace",
o que esse linspace faz?
-
Ele simplesmente cria pontos
linearmente, igualmente espaçados,
-
vamos dizer assim.
-
Então, o que essa funçãozinha
aqui está fazendo?
-
Eu vou criar 5 pontos
entre 0 e 10,
-
e esses pontos vão ser
linearmente espaçados,
-
então 0, 2.5, 5, 7.5, 10.
-
Tenho 5 pontos e a distância
entre eles é igual.
-
Outras funções auxiliares:
-
eu posso criar uma matriz
só com zeros no Python,
-
utilizando a função
"np.zeros".
-
E, aqui, eu posso passar
como entrada,
-
como parâmetro
para essa função,
-
a dimensão da matriz
que eu quero criar.
-
Então, eu vou criar
uma matriz de zeros
-
com dimensões
de 2 linhas e 3 colunas.
-
Da mesma forma, eu posso criar
uma matriz de números uns,
-
utilizando o "np.ones".
-
Vou passar aqui, eu quero criar
uma matriz de 3 linhas e 2 colunas
-
só com números uns.
-
Então, está aqui a nossa matriz
de zeros e a nossa matriz de uns.
-
E a gente pode, também,
concatenar esses vetores,
-
ou seja, eu posso juntar dois
vetores, ou juntar duas matrizes.
-
Então, aqui, por exemplo, eu tenho
uma matriz chamada "array1"
-
e essa matriz é "np.array",
primeira linha, segunda linha,
-
cada uma com duas colunas.
-
E eu posso ter um vetor,
uma matriz que, na verdade,
-
aqui, vai ter uma linha só,
uma linha e duas colunas.
-
Então, se eu concatenar esses dois
arrays aqui, esses dois vetores,
-
essas duas matrizes,
aqui no caso,
-
eu vou ter, na verdade,
no final, uma matriz,
-
esse array concatenado
vai adicionar essa linha
-
nesse vetor original
que tinha só duas linhas.
-
Então, eu vou ter um vetor
de 3 linhas e 2 colunas,
-
uma matriz, no caso,
de 3 linhas e 2 colunas.
-
Esse parâmetro aqui,
"axis", significa:
-
quando é 0, eu vou
adicionar nas linhas,
-
quando são colunas, eu
vou adicionar nas colunas,
-
então um eu vou adicionar embaixo,
o outro eu vou adicionar ao lado,
-
é como se fosse isso.
-
Então, aqui, eu tenho um exemplo
tanto adicionando linhas
-
a uma matriz original,
-
quanto adicionando colunas
a uma matriz original.
-
Então, se a gente
rodar esse exemplo,
-
eu tenho a matriz 1,
2 por 2,
-
e a matriz 2, que é uma linha
por duas colunas.
-
Quando eu concateno elas
utilizando o eixo 0, o axis 0,
-
eu vou adicionar
uma linha a mais.
-
No outro exemplo,
no debaixo,
-
eu tenho uma matriz
de duas linhas e uma coluna,
-
e eu vou concatenar
um array nas colunas,
-
então eu vou adicionar
duas colunas diferentes.
-
Então, eu continuo com o 7 e 8,
vou adicionar o 1, 3, 2, 4 aqui,
-
como colunas novas
nessa matriz original.
-
E, por último,
para fechar o nosso lab,
-
eu também posso utilizar uma função
de reshape nos meus dados,
-
nos meus arrays, nos meus
vetores e matrizes.
-
O que o reshape vai fazer?
-
Eu consigo alterar o formato
dessa matriz ou desse array.
-
Então, imagina que eu tenho
uma matriz, um array, na verdade,
-
que eu tenho 6 elementos
nesse array.
-
Eu posso fazer um reshape
nesse dado, nessa matriz,
-
e transformá-lo em uma matriz
de duas linhas e três colunas.
-
O único ponto importante
para a gente pensar é:
-
no final, essa conta
tem que fechar,
-
então, se eu tenho 6 colunas,
6 números, 6 elementos nesse vetor,
-
e eu quero transformá-lo
em uma matriz,
-
as dimensões, aqui,
têm que multiplicar
-
e dar o mesmo resultado
que a quantidade de elementos
-
desse vetor original.
-
Então, se eu tenho 6 elementos,
2 vezes 3 tem que dar 6.
-
Eu poderia, também,
fazer 3 por 2, ou 6 por 1,
-
mas eu não poderia fazer
2 por 4, porque daria erro.
-
Então, se a gente rodar
aqui, tem o array original,
-
e esse array, quando eu fizer
o reshape de 2 por 3 dele,
-
ele vai reajustar
esses elementos
-
em uma matriz de duas
linhas e três colunas.
-
Se eu colocasse
"4" aqui, daria erro.
-
Por que daria erro?
-
Porque eu só tenho
6 elementos,
-
para fazer um reshape de 2 e 4,
eu teria que ter 8 elementos.
-
Então, o único ponto
de atenção seria esse.
-
Então, agora você já sabe
muito sobre IA generativa
-
e já deu os seus primeiros
passos sobre álgebra linear
-
para conseguir,
você mesmo,
-
implementar os seus próprios
modelos de IA generativa.