# file name 'egitim.py' from model import ileri_gecis from islemler import carpim, transpoze, embed, pozisyonel_encoding, transformer_blok, dogrusal, topla, katman_norm, cok_baslikli_attention def cross_entropy_kayip(olasiliklar, hedef_index): p = max(olasiliklar[hedef_index], 1e-10) y = (p - 1) / (p + 1) y2 = y * y sonuc = 0.0 for i in range(100): n = 2 * i + 1 sonuc += (y ** n) / n return -2 * sonuc def softmax_cross_entropy_gradyan(olasiliklar, hedef_index): grad = olasiliklar[:] grad[hedef_index] -= 1.0 return grad def dogrusal_gradyan(grad_cikti, x, W): grad_x = carpim(grad_cikti, transpoze(W)) grad_W = carpim(transpoze(x), grad_cikti) grad_b = [sum(grad_cikti[i][j] for i in range(len(grad_cikti))) for j in range(len(grad_cikti[0]))] return grad_x, grad_W, grad_b def guncelle(agirlik, grad, ogrenme_hizi): return [ [agirlik[i][j] - ogrenme_hizi * grad[i][j] for j in range(len(agirlik[0]))] for i in range(len(agirlik)) ] def vektor_guncelle(vektor, grad, ogrenme_hizi): return [vektor[i] - ogrenme_hizi * grad[i] for i in range(len(vektor))] def egitim_adimi(ag, token_indexleri, hedef_index, ogrenme_hizi=0.001): from islemler import embed, pozisyonel_encoding, topla, transformer_blok olasiliklar = ileri_gecis(ag, token_indexleri) kayip = cross_entropy_kayip(olasiliklar, hedef_index) grad = softmax_cross_entropy_gradyan(olasiliklar, hedef_index) grad_matris = [grad] vektorler = embed(token_indexleri, ag.embedding) pe = pozisyonel_encoding(len(token_indexleri), ag.model_boyutu) x = topla(vektorler, pe) ara_x = [x] for katman in ag.katmanlar: x = transformer_blok(x, katman) ara_x.append(x) son_token = [ara_x[-1][-1]] grad_x, grad_W, grad_b = dogrusal_gradyan(grad_matris, son_token, ag.cikti_W) ag.cikti_W = guncelle(ag.cikti_W, grad_W, ogrenme_hizi) ag.cikti_b = vektor_guncelle(ag.cikti_b, grad_b, ogrenme_hizi) son_token_grad = grad_x[0] grad_katman = [son_token_grad for _ in range(len(token_indexleri))] for i in reversed(range(len(ag.katmanlar))): grad_katman = transformer_blok_gradyan( grad_katman, ara_x[i], ag.katmanlar[i] ) return kayip def gelu_gradyan(x): PI = 3.141592653589793 k = (2 / PI) ** 0.5 ic = k * (x + 0.044715 * x**3) ic = max(-20.0, min(20.0, ic)) e = 2.718281828459 exp2 = e ** (2 * ic) tanh_ic = (exp2 - 1) / (exp2 + 1) dtanh = 1 - tanh_ic ** 2 dic = k * (1 + 3 * 0.044715 * x**2) return 0.5 * (1 + tanh_ic) + 0.5 * x * dtanh * dic def ileri_besleme_gradyan(grad_cikti, x, ff_agirliklar): ara = [[0.0] * len(ff_agirliklar.b1) for _ in range(len(x))] ara_aktif = dogrusal(x, ff_agirliklar.W1, ff_agirliklar.b1) aktivasyon = [[max(0.0, v) for v in satir] for satir in ara_aktif] grad_x2, grad_W2, grad_b2 = dogrusal_gradyan(grad_cikti, aktivasyon, ff_agirliklar.W2) grad_aktif = [ [grad_x2[i][j] * gelu_gradyan(ara_aktif[i][j]) for j in range(len(ara_aktif[0]))] for i in range(len(ara_aktif)) ] grad_x1, grad_W1, grad_b1 = dogrusal_gradyan(grad_aktif, x, ff_agirliklar.W1) return grad_x1, grad_W1, grad_b1, grad_W2, grad_b2 def transformer_blok_gradyan(grad_cikti, x, katman_agirliklar): if isinstance(grad_cikti[0], (int, float)): grad_cikti = [grad_cikti] att_cikti = cok_baslikli_attention(x, katman_agirliklar.attention) x_att = katman_norm(topla(x, att_cikti), katman_agirliklar.gamma1, katman_agirliklar.beta1) grad_ln2 = [] grad_gamma2_toplam = [0.0] * len(katman_agirliklar.gamma2) grad_beta2_toplam = [0.0] * len(katman_agirliklar.beta2) for i in range(len(grad_cikti)): gx, gg, gb = katman_norm_gradyan(grad_cikti[i], x_att[i], katman_agirliklar.gamma2) grad_ln2.append(gx) for j in range(len(gg)): grad_gamma2_toplam[j] += gg[j] grad_beta2_toplam[j] += gb[j] katman_agirliklar.gamma2 = vektor_guncelle(katman_agirliklar.gamma2, grad_gamma2_toplam, 0.001) katman_agirliklar.beta2 = vektor_guncelle(katman_agirliklar.beta2, grad_beta2_toplam, 0.001) grad_ff_x, gW1, gb1, gW2, gb2 = ileri_besleme_gradyan(grad_ln2, x_att, katman_agirliklar.ff) katman_agirliklar.ff.W1 = guncelle(katman_agirliklar.ff.W1, gW1, 0.001) katman_agirliklar.ff.b1 = vektor_guncelle(katman_agirliklar.ff.b1, gb1, 0.001) katman_agirliklar.ff.W2 = guncelle(katman_agirliklar.ff.W2, gW2, 0.001) katman_agirliklar.ff.b2 = vektor_guncelle(katman_agirliklar.ff.b2, gb2, 0.001) grad_x_att = [ [grad_ff_x[i][j] + grad_ln2[i][j] for j in range(len(grad_ff_x[0]))] for i in range(len(grad_ff_x)) ] grad_ln1 = [] grad_gamma1_toplam = [0.0] * len(katman_agirliklar.gamma1) grad_beta1_toplam = [0.0] * len(katman_agirliklar.beta1) for i in range(len(grad_x_att)): gx, gg, gb = katman_norm_gradyan(grad_x_att[i], x[i], katman_agirliklar.gamma1) grad_ln1.append(gx) for j in range(len(gg)): grad_gamma1_toplam[j] += gg[j] grad_beta1_toplam[j] += gb[j] katman_agirliklar.gamma1 = vektor_guncelle(katman_agirliklar.gamma1, grad_gamma1_toplam, 0.001) katman_agirliklar.beta1 = vektor_guncelle(katman_agirliklar.beta1, grad_beta1_toplam, 0.001) return grad_ln1 def katman_norm_gradyan(grad_cikti, x, gamma, eps=1e-5): n = len(x) ortalama = sum(x) / n varyans = sum((v - ortalama) ** 2 for v in x) / n std = (varyans + eps) ** 0.5 x_norm = [(v - ortalama) / std for v in x] grad_gamma = [grad_cikti[i] * x_norm[i] for i in range(n)] grad_beta = grad_cikti[:] grad_x_norm = [grad_cikti[i] * gamma[i] for i in range(n)] grad_varyans = sum(grad_x_norm[i] * (x[i] - ortalama) for i in range(n)) * (-0.5) * (varyans + eps) ** (-1.5) grad_ortalama = sum(-grad_x_norm[i] / std for i in range(n)) + grad_varyans * sum(-2 * (x[i] - ortalama) for i in range(n)) / n grad_x = [ grad_x_norm[i] / std + grad_varyans * 2 * (x[i] - ortalama) / n + grad_ortalama / n for i in range(n) ] return grad_x, grad_gamma, grad_beta