Tensor adalah wadah seluruh data di TensorFlow, sama seperti perannya di PyTorch pada section sebelumnya. Di TensorFlow, wadah itu datang dalam dua wujud yang perlu kita bedakan sejak awal: tf.constant untuk nilai tetap dan tf.Variable untuk nilai yang boleh berubah — misalnya bobot model yang terus diperbarui saat pelatihan. Keduanya mempunyai aturan dtype, shape, dan kerja sama dengan NumPy yang sedikit berbeda dari torch.Tensor. Chapter ini membedah kedua wujud tersebut, menjalankan operasi inti — penjumlahan, perkalian matriks, dan reduksi dengan axis — lalu menunjukkan bahwa eager execution membuat nilai tensor bisa dipakai langsung dalam if Python biasa. Semua contoh memakai angka kecil yang bisa dihitung tangan dan diuji nyata di mesin ini.

tf.constant dan tf.Variable #

tf.constant membuat tensor yang isinya terkunci: tidak ada operasi penugasan ulang yang dibenarkan. tf.Variable sebaliknya menyimpan status yang dapat diperbarui lewat keluarga metode assign, dan secara bawaan ditandai trainable=True sehingga optimizer tahu parameter mana yang perlu dipelajari. Berkas konstanta_dan_variable.py membandingkan keduanya sekaligus menguji jembatan NumPy:

python
"""Membandingkan tf.constant, tf.Variable, dan jembatan NumPy."""

import os

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"

import numpy as np
import tensorflow as tf

angka = tf.constant([1, 2, 3])
pecahan = tf.constant([1.5, 2.5])
dari_numpy = tf.constant(np.array([1.5, 2.5]))

print("angka      : dtype", angka.dtype, "| shape", angka.shape)
print("pecahan    : dtype", pecahan.dtype, "| shape", pecahan.shape)
print("dari_numpy : dtype", dari_numpy.dtype, "| shape", dari_numpy.shape)

print()
w = tf.Variable(2.0)
print("w awal            :", w.numpy())
w.assign(7.0)
print("setelah assign(7) :", w.numpy())
w.assign_add(3.0)
print("setelah assign_add:", w.numpy())
w.assign_sub(4.0)
print("setelah assign_sub:", w.numpy())
print("w trainable       :", w.trainable, "| dtype", w.dtype, "| shape", w.shape)

print()
arr = np.array([10.0, 20.0])
t = tf.constant(arr)
arr[0] = 99.0
print("array NumPy berubah    :", arr)
print("tf.constant(arr) tetap :", t.numpy())

tampilan = t.numpy()
tampilan[1] = -5.0
print("tampilan berubah       :", tampilan)
print("tensor asal tetap      :", t.numpy())

Output yang Dihasilkan:

text
angka      : dtype <dtype: 'int32'> | shape (3,)
pecahan    : dtype <dtype: 'float32'> | shape (2,)
dari_numpy : dtype <dtype: 'float64'> | shape (2,)

w awal            : 2.0
setelah assign(7) : 7.0
setelah assign_add: 10.0
setelah assign_sub: 6.0
w trainable       : True | dtype <dtype: 'float32'> | shape ()

array NumPy berubah    : [99. 20.]
tf.constant(arr) tetap : [10. 20.]
tampilan berubah       : [10. -5.]
tensor asal tetap      : [10. 20.]

Mari kita telaah kode di atas baris per baris:

  1. Baris 10-12 (tiga tensor): tf.constant menyimpulkan dtype dari sumbernya — daftar bilangan bulat menjadi int32, daftar pecahan menjadi float32, sedangkan array NumPy menyerahkan dtypenya sendiri sehingga np.array([1.5, 2.5]) yang bawaannya float64 menghasilkan tensor float64.
  2. Baris 19 (tf.Variable(2.0)): membuat satu parameter berskalar bertipe float32 — tipe standar pelatihan deep learning.
  3. Baris 21-26 (keluarga assign): assign menimpa nilai menjadi 7.0, assign_add menambah 3.0 menjadi 10.0, dan assign_sub mengurangi 4.0 menjadi 6.0. Pembaruan nilai hanya sah lewat metode seperti ini; penugasan per elemen w[0] = 9.0 justru menimbulkan TypeError.
  4. Baris 27 (w.trainable): nilai True menandakan Variable ini layak dilatih optimizer — properti yang akan relevan pada Chapter automatic differentiation.
  5. Baris 30-34 (jembatan pertama): tf.constant(arr) menyalin data, terbukti dari arr yang diubah menjadi [99, 20] sementara tensor tetap [10, 20].
  6. Baris 36-39 (jembatan kedua): .numpy() menghasilkan array NumPy yang berdiri terpisah — mengubah tampilan tidak mengubah tensor asal. Perilaku ini berbeda dari torch.from_numpy di Chapter Konsep Tensor yang sengaja berbagi blok memori.

Operasi Tensor: add, matmul, dan Reduksi #

Operasi tensor TensorFlow tersedia dalam dua rupa: fungsi eksplisit seperti tf.add dan tf.matmul, serta operator Python seperti + dan @ yang menunjuk fungsi yang sama. Reduksi seperti tf.reduce_mean punya parameter axis yang menentukan sumbu mana yang diruntuhkan. Berkas operasi_tensor.py mempraktikkan ketiganya:

python
"""Operasi dasar tensor: add, matmul, reduce_mean, dan jembatan NumPy."""

import os

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"

import numpy as np
import tensorflow as tf

A = tf.constant([[1.0, 2.0, 3.0],
                 [4.0, 5.0, 6.0]])
B = tf.constant([[10.0, 20.0],
                 [30.0, 40.0],
                 [50.0, 60.0]])

print("A       : shape", A.shape)
print(A.numpy())
print("B       : shape", B.shape)
print(B.numpy())

print()
print("tf.add(A, A) :")
print(tf.add(A, A).numpy())
print("A + A (operator sama) :")
print((A + A).numpy())

C = tf.matmul(A, B)
print("tf.matmul(A, B) : shape", C.shape)
print(C.numpy())

print()
nilai = tf.constant([[7.0, 3.0],
                     [9.0, 5.0]])
print("reduce_mean semua  :", tf.reduce_mean(nilai).numpy())
print("reduce_mean axis=0 :", tf.reduce_mean(nilai, axis=0).numpy())
print("reduce_mean axis=1 :", tf.reduce_mean(nilai, axis=1).numpy())

print()
proba = tf.constant([0.2, 0.5, 0.9])
arr = proba.numpy()
skala = arr * 10
kembali = tf.constant(skala)
print("tensor -> numpy :", arr)
print("numpy * 10      :", skala)
print("kembali ke TF   :", kembali.numpy())

print()
loss = tf.constant(0.25)
if loss.numpy() < 0.5:
    print("loss", loss.numpy(), "< 0.5 -> pelatihan dihentikan lebih awal")

Output yang Dihasilkan:

text
A       : shape (2, 3)
[[1. 2. 3.]
 [4. 5. 6.]]
B       : shape (3, 2)
[[10. 20.]
 [30. 40.]
 [50. 60.]]

tf.add(A, A) :
[[ 2.  4.  6.]
 [ 8. 10. 12.]]
A + A (operator sama) :
[[ 2.  4.  6.]
 [ 8. 10. 12.]]
tf.matmul(A, B) : shape (2, 2)
[[220. 280.]
 [490. 640.]]

reduce_mean semua  : 6.0
reduce_mean axis=0 : [8. 4.]
reduce_mean axis=1 : [5. 7.]

tensor -> numpy : [0.2 0.5 0.9]
numpy * 10      : [2. 5. 9.]
kembali ke TF   : [2. 5. 9.]

loss 0.25 < 0.5 -> pelatihan dihentikan lebih awal

Mari kita telaah kode di atas baris per baris:

  1. Baris 10-14 (A dan B): dua matriks kecil — A berbentuk (2, 3) dan B berbentuk (3, 2). Bentuk dalam mengikuti kaidah perkalian matriks dari Chapter Operasi Matriks : jumlah kolom A harus sama dengan jumlah baris B.
  2. Baris 22-25 (tf.add vs +): keduanya menghasilkan matriks yang persis sama — penjumlahan per elemen. Operator Python hanyalah nama pendek untuk fungsi TensorFlow.
  3. Baris 27-29 (tf.matmul): hasil (2, 3) @ (3, 2) berbentuk (2, 2) dengan nilai konkret — baris pertama: 1×10 + 2×30 + 3×50 = 220 dan 1×20 + 2×40 + 3×60 = 280; baris kedua menghasilkan 490 dan 640.
  4. Baris 32-36 (tf.reduce_mean dan axis): tanpa axis, seluruh elemen dirata-ratakan menjadi 6.0. Dengan axis=0, sumbu baris diruntuhkan sehingga tiap kolom dirata-ratakan — kolom pertama (7+9)/2 = 8, kolom kedua (3+5)/2 = 4. Dengan axis=1, sumbu kolom yang diruntuhkan sehingga tiap baris dirata-ratakan — (7+3)/2 = 5 dan (9+5)/2 = 7.
  5. Baris 39-45 (putaran NumPy): tensor probabilitas berpindah ke NumPy lewat .numpy(), diskalakan sepuluh kali dengan operasi NumPy, lalu kembali ke TensorFlow lewat tf.constant — pola yang sering kita pakai saat mencampur kode NumPy lama dengan model TensorFlow.
  6. Baris 48-50 (if pada nilai tensor): karena eager, loss.numpy() langsung menyediakan angka 0.25 untuk dibandingkan — sesuatu yang mustahil dilakukan pada graf tunda di era TensorFlow 1.x.

Tiga Wadah dalam Satu Tabel #

Tabel berikut merangkum ketiga wadah yang kini kita kenal — termasuk np.ndarray dari section dasar Python:

Aspektf.constanttf.Variablenp.ndarray
Sifat nilaitetap, tak bisa diubahberubah lewat assignberubah lewat penugasan
Direkam GradientTapehanya dengan watch()otomatistidak, konversi dulu
Ditandai trainabletidakya secara bawaantidak berlaku
Jembatan data.numpy().numpy()tf.constant(arr) menyalin

Pembahasan mendalam tentang tensor di sisi PyTorch tersedia pada Konsep Tensor , sedangkan rujukan resmi TensorFlow ada di tensorflow.org/guide/tensor dan halaman API tf.Variable .

Ringkasan #

Kita kini menguasai dua wadah data TensorFlow: tf.constant untuk nilai tetap dan tf.Variable untuk parameter yang diperbarui lewat assign, lengkap dengan jebakan dtype float64 dari NumPy dan jembatan dua arah yang menyalin data. Operasi inti — penjumlahan per elemen, perkalian matriks, dan reduce_mean dengan axis — berjalan eager sehingga hasilnya bisa langsung diinspeksi dan dipakai dalam alur Python. Satu kemampuan belum kita bahas: bagaimana TensorFlow tahu seberapa besar assign_sub harus menggeser nilai. Jawabannya adalah tf.GradientTape, topik Chapter berikutnya.