Wprowadzenie do tensorów

Zobacz na TensorFlow.org Uruchom w Google Colab Wyświetl źródło na GitHub Pobierz notatnik
import tensorflow as tf
import numpy as np

Tensory są tablice wielowymiarowe z rodzaju jednolite (zwany w dtype ). Można zobaczyć wszystkie obsługiwane dtypes w tf.dtypes.DType .

Jeśli jesteś zaznajomiony z NumPy , tensory są (niby) jak np.arrays .

Wszystkie tensory są niezmienne, podobnie jak liczby i łańcuchy w Pythonie: nigdy nie możesz zaktualizować zawartości tensora, a jedynie utworzyć nowy.

Podstawy

Stwórzmy kilka podstawowych tensorów.

Oto tensor „skalarny” lub „ranga 0” . Skalar zawiera pojedynczą wartość i nie zawiera „osi”.

# This will be an int32 tensor by default; see "dtypes" below.
rank_0_tensor = tf.constant(4)
print(rank_0_tensor)
tf.Tensor(4, shape=(), dtype=int32)

Tensor „wektorowy” lub „ranga-1” jest jak lista wartości. Wektor ma jedną oś:

# Let's make this a float tensor.
rank_1_tensor = tf.constant([2.0, 3.0, 4.0])
print(rank_1_tensor)
tf.Tensor([2. 3. 4.], shape=(3,), dtype=float32)

Tensor „macierzy” lub „rangi-2” ma dwie osie:

# If you want to be specific, you can set the dtype (see below) at creation time
rank_2_tensor = tf.constant([[1, 2],
                             [3, 4],
                             [5, 6]], dtype=tf.float16)
print(rank_2_tensor)
tf.Tensor(
[[1. 2.]
 [3. 4.]
 [5. 6.]], shape=(3, 2), dtype=float16)
Skalarną kształt: [] Wektor, kształt: [3] Matryca, kształt: [3, 2]
Skalar, liczba 4Linia z 3 sekcjami, z których każda zawiera numer.Siatka 3x2, z każdą komórką zawierającą liczbę.

Tensory mogą mieć więcej osi; oto tensor z trzema osiami:

# There can be an arbitrary number of
# axes (sometimes called "dimensions")
rank_3_tensor = tf.constant([
  [[0, 1, 2, 3, 4],
   [5, 6, 7, 8, 9]],
  [[10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19]],
  [[20, 21, 22, 23, 24],
   [25, 26, 27, 28, 29]],])

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

Istnieje wiele sposobów wizualizacji tensora z więcej niż dwiema osiami.

3-osiowy tensora kształt: [3, 2, 5]

Można konwertować tensora do tablicy numpy albo za pomocą np.array lub tensor.numpy metodę:

np.array(rank_2_tensor)
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)
rank_2_tensor.numpy()
array([[1., 2.],
       [3., 4.],
       [5., 6.]], dtype=float16)

Tensory często zawierają pływaki i int, ale mają wiele innych typów, w tym:

  • Liczby zespolone
  • smyczki

Podstawa tf.Tensor klasy wymaga tensory jest „prostokątną” --- czyli wzdłuż każdej osi, każdy element ma takie same wymiary. Istnieją jednak wyspecjalizowane typy tensorów, które mogą obsługiwać różne kształty:

Możesz wykonać podstawową matematykę na tensorach, w tym dodawanie, mnożenie elementów i mnożenie macierzy.

a = tf.constant([[1, 2],
                 [3, 4]])
b = tf.constant([[1, 1],
                 [1, 1]]) # Could have also said `tf.ones([2,2])`

print(tf.add(a, b), "\n")
print(tf.multiply(a, b), "\n")
print(tf.matmul(a, b), "\n")
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)
print(a + b, "\n") # element-wise addition
print(a * b, "\n") # element-wise multiplication
print(a @ b, "\n") # matrix multiplication
tf.Tensor(
[[2 3]
 [4 5]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[1 2]
 [3 4]], shape=(2, 2), dtype=int32) 

tf.Tensor(
[[3 3]
 [7 7]], shape=(2, 2), dtype=int32)

Tensory są używane we wszelkiego rodzaju operacjach (ops).

c = tf.constant([[4.0, 5.0], [10.0, 1.0]])

# Find the largest value
print(tf.reduce_max(c))
# Find the index of the largest value
print(tf.argmax(c))
# Compute the softmax
print(tf.nn.softmax(c))
tf.Tensor(10.0, shape=(), dtype=float32)
tf.Tensor([1 0], shape=(2,), dtype=int64)
tf.Tensor(
[[2.6894143e-01 7.3105854e-01]
 [9.9987662e-01 1.2339458e-04]], shape=(2, 2), dtype=float32)

O kształtach

Tensory mają kształty. Trochę słownictwa:

  • Kształt: długość (liczba elementów) z każdej z osi tensora.
  • Rank: Liczba osi tensorowych. Skalar ma rangę 0, wektor ma rangę 1, macierz ma rangę 2.
  • lub Wymiar: Szczególny wymiar tensora.
  • Rozmiar: Całkowita liczba elementów w tensora, kształt produktu wektorze.

Tensory i tf.TensorShape obiekty mają dogodne właściwości dostępu do nich:

rank_4_tensor = tf.zeros([3, 2, 4, 5])
Notę A-4 tensora kształt: [3, 2, 4, 5]
Kształt tensora jest jak wektor.Tensor 4-osiowy
print("Type of every element:", rank_4_tensor.dtype)
print("Number of axes:", rank_4_tensor.ndim)
print("Shape of tensor:", rank_4_tensor.shape)
print("Elements along axis 0 of tensor:", rank_4_tensor.shape[0])
print("Elements along the last axis of tensor:", rank_4_tensor.shape[-1])
print("Total number of elements (3*2*4*5): ", tf.size(rank_4_tensor).numpy())
Type of every element: <dtype: 'float32'>
Number of axes: 4
Shape of tensor: (3, 2, 4, 5)
Elements along axis 0 of tensor: 3
Elements along the last axis of tensor: 5
Total number of elements (3*2*4*5):  120

Chociaż osie są często określane przez ich indeksy, zawsze należy śledzić znaczenie każdego z nich. Często osie są uporządkowane od globalnego do lokalnego: najpierw oś wsadu, a następnie wymiary przestrzenne i cechy dla każdej lokalizacji na końcu. W ten sposób wektory cech są ciągłymi obszarami pamięci.

Typowa kolejność osi
Śledź, czym jest każda oś. Tensor 4-osiowy może być następujący: Partia, Szerokość, Wysokość, Funkcje

Indeksowanie

Indeksowanie jednoosiowe

TensorFlow następujące standardowe zasady indeksowania Python, podobne do indeksowania listę lub ciąg znaków w Pythonie , a podstawowe zasady NumPy indeksowania.

  • Indeksy zaczynają się od 0
  • indeksy ujemne liczą się wstecz od końca
  • dwukropek, : , służą do plasterków: start:stop:step
rank_1_tensor = tf.constant([0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
print(rank_1_tensor.numpy())
[ 0  1  1  2  3  5  8 13 21 34]

Indeksowanie skalarem usuwa oś:

print("First:", rank_1_tensor[0].numpy())
print("Second:", rank_1_tensor[1].numpy())
print("Last:", rank_1_tensor[-1].numpy())
First: 0
Second: 1
Last: 34

Indeksowanie z : plaster utrzymuje oś:

print("Everything:", rank_1_tensor[:].numpy())
print("Before 4:", rank_1_tensor[:4].numpy())
print("From 4 to the end:", rank_1_tensor[4:].numpy())
print("From 2, before 7:", rank_1_tensor[2:7].numpy())
print("Every other item:", rank_1_tensor[::2].numpy())
print("Reversed:", rank_1_tensor[::-1].numpy())
Everything: [ 0  1  1  2  3  5  8 13 21 34]
Before 4: [0 1 1 2]
From 4 to the end: [ 3  5  8 13 21 34]
From 2, before 7: [1 2 3 5 8]
Every other item: [ 0  1  3  8 21]
Reversed: [34 21 13  8  5  3  2  1  1  0]

Indeksowanie wieloosiowe

Tensory o wyższych rangach są indeksowane przez przekazywanie wielu indeksów.

Dokładnie te same zasady, co w przypadku pojedynczej osi, dotyczą każdej osi niezależnie.

print(rank_2_tensor.numpy())
[[1. 2.]
 [3. 4.]
 [5. 6.]]

Po przekazaniu liczby całkowitej dla każdego indeksu wynikiem jest skalar.

# Pull out a single value from a 2-rank tensor
print(rank_2_tensor[1, 1].numpy())
4.0

Możesz indeksować za pomocą dowolnej kombinacji liczb całkowitych i wycinków:

# Get row and column tensors
print("Second row:", rank_2_tensor[1, :].numpy())
print("Second column:", rank_2_tensor[:, 1].numpy())
print("Last row:", rank_2_tensor[-1, :].numpy())
print("First item in last column:", rank_2_tensor[0, -1].numpy())
print("Skip the first row:")
print(rank_2_tensor[1:, :].numpy(), "\n")
Second row: [3. 4.]
Second column: [2. 4. 6.]
Last row: [5. 6.]
First item in last column: 2.0
Skip the first row:
[[3. 4.]
 [5. 6.]]

Oto przykład z tensorem 3-osiowym:

print(rank_3_tensor[:, :, 4])
tf.Tensor(
[[ 4  9]
 [14 19]
 [24 29]], shape=(3, 2), dtype=int32)
Wybór ostatniej funkcji we wszystkich lokalizacjach w każdym przykładzie w partii
Tensor 3x2x5 ze wszystkimi wartościami w indeksie 4 ostatniej wybranej osi.Wybrane wartości zapakowane w dwuosiowy tensor.

Przeczytać podręcznik krojenia tensorowy aby dowiedzieć się w jaki sposób można zastosować indeksowanie manipulowania pojedynczych elementów w tensorów.

Manipulowanie kształtami

Zmiana kształtu tensora jest bardzo przydatna.

# Shape returns a `TensorShape` object that shows the size along each axis
x = tf.constant([[1], [2], [3]])
print(x.shape)
(3, 1)
# You can convert this object into a Python list, too
print(x.shape.as_list())
[3, 1]

Możesz przekształcić tensor w nowy kształt. tf.reshape działanie jest szybkie i tanie, jak podstawowe dane nie muszą być powielane.

# You can reshape a tensor to a new shape.
# Note that you're passing in a list
reshaped = tf.reshape(x, [1, 3])
print(x.shape)
print(reshaped.shape)
(3, 1)
(1, 3)

Dane zachowują swój układ w pamięci i tworzony jest nowy tensor o żądanym kształcie, wskazujący te same dane. TensorFlow używa porządkowania pamięci „wiersz-główny” w stylu C, gdzie inkrementacja indeksu z prawej strony odpowiada pojedynczemu krokowi w pamięci.

print(rank_3_tensor)
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]

 [[20 21 22 23 24]
  [25 26 27 28 29]]], shape=(3, 2, 5), dtype=int32)

Jeśli spłaszczysz tensor, możesz zobaczyć, jaki porządek jest ułożony w pamięci.

# A `-1` passed in the `shape` argument says "Whatever fits".
print(tf.reshape(rank_3_tensor, [-1]))
tf.Tensor(
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 24 25 26 27 28 29], shape=(30,), dtype=int32)

Zazwyczaj jedynie rozsądne wykorzystanie tf.reshape jest łączenie lub podziel sąsiadujące osie (lub dodawania / usuwania 1 s).

W przypadku tego tensora 3x2x5 zmiana kształtu na (3x2)x5 lub 3x(2x5) jest rozsądnym rozwiązaniem, ponieważ plasterki nie mieszają się:

print(tf.reshape(rank_3_tensor, [3*2, 5]), "\n")
print(tf.reshape(rank_3_tensor, [3, -1]))
tf.Tensor(
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]
 [25 26 27 28 29]], shape=(6, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5  6  7  8  9]
 [10 11 12 13 14 15 16 17 18 19]
 [20 21 22 23 24 25 26 27 28 29]], shape=(3, 10), dtype=int32)
Kilka dobrych zmian.
Tensor 3x2x5Te same dane przekształcone do (3x2)x5Te same dane przekształcone do 3x(2x5)

Zmiana kształtu będzie "działać" dla każdego nowego kształtu z taką samą całkowitą liczbą elementów, ale nie przyniesie niczego użytecznego, jeśli nie zachowasz kolejności osi.

Zamiana osi w tf.reshape nie działa; Need You tf.transpose za to.

# Bad examples: don't do this

# You can't reorder axes with reshape.
print(tf.reshape(rank_3_tensor, [2, 3, 5]), "\n") 

# This is a mess
print(tf.reshape(rank_3_tensor, [5, 6]), "\n")

# This doesn't work at all
try:
  tf.reshape(rank_3_tensor, [7, -1])
except Exception as e:
  print(f"{type(e).__name__}: {e}")
tf.Tensor(
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]
  [10 11 12 13 14]]

 [[15 16 17 18 19]
  [20 21 22 23 24]
  [25 26 27 28 29]]], shape=(2, 3, 5), dtype=int32) 

tf.Tensor(
[[ 0  1  2  3  4  5]
 [ 6  7  8  9 10 11]
 [12 13 14 15 16 17]
 [18 19 20 21 22 23]
 [24 25 26 27 28 29]], shape=(5, 6), dtype=int32) 

InvalidArgumentError: Input to reshape is a tensor with 30 values, but the requested shape requires a multiple of 7 [Op:Reshape]
Kilka złych zmian.
Nie możesz zmienić kolejności osi, użyj do tego tf.transposeWszystko, co łączy ze sobą fragmenty danych, jest prawdopodobnie złe.Nowy kształt musi dokładnie pasować.

Możesz natknąć się na nie do końca określone kształty. Albo kształt zawiera None (oś długości nie jest znany) lub cały kształt None (ranking tensora jest znany).

Z wyjątkiem tf.RaggedTensor takie kształty będą występować tylko w kontekście symbolicznych API wykres budowania TensorFlow za:

Więcej na DTypes

Sprawdzamy tf.Tensor typu danych użyć „s Tensor.dtype nieruchomości.

Podczas tworzenia tf.Tensor z obiektu Pythona można opcjonalnie określić typ danych.

Jeśli tego nie zrobisz, TensorFlow wybierze typ danych, który może reprezentować Twoje dane. TensorFlow konwertuje liczby całkowite Python tf.int32 i Python liczb zmiennoprzecinkowych do tf.float32 . W przeciwnym razie TensorFlow używa tych samych reguł, których używa NumPy podczas konwersji na tablice.

Możesz przesyłać z tekstu na tekst.

the_f64_tensor = tf.constant([2.2, 3.3, 4.4], dtype=tf.float64)
the_f16_tensor = tf.cast(the_f64_tensor, dtype=tf.float16)
# Now, cast to an uint8 and lose the decimal precision
the_u8_tensor = tf.cast(the_f16_tensor, dtype=tf.uint8)
print(the_u8_tensor)
tf.Tensor([2 3 4], shape=(3,), dtype=uint8)

Nadawanie

Rozsyłanie to pojęcie zapożyczone z równoważnej funkcji w NumPy . Krótko mówiąc, w pewnych warunkach mniejsze tensory są automatycznie „rozciągane”, aby pasowały do ​​większych tensorów podczas wykonywania na nich połączonych operacji.

Najprostszym i najczęstszym przypadkiem jest próba pomnożenia lub dodania tensora do skalara. W takim przypadku skalar jest emitowany tak, aby miał ten sam kształt, co inny argument.

x = tf.constant([1, 2, 3])

y = tf.constant(2)
z = tf.constant([2, 2, 2])
# All of these are the same computation
print(tf.multiply(x, 2))
print(x * y)
print(x * z)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)
tf.Tensor([2 4 6], shape=(3,), dtype=int32)

Podobnie osie o długości 1 można rozciągnąć, aby dopasować inne argumenty. Oba argumenty można rozciągnąć w tym samym obliczeniu.

W tym przypadku macierz 3x1 jest mnożona elementowo przez macierz 1x4, aby uzyskać macierz 3x4. Uwaga jak prowadzące 1 jest wyposażenie dodatkowe, jest kształt Y [4] .

# These are the same computations
x = tf.reshape(x,[3,1])
y = tf.range(1, 5)
print(x, "\n")
print(y, "\n")
print(tf.multiply(x, y))
tf.Tensor(
[[1]
 [2]
 [3]], shape=(3, 1), dtype=int32) 

tf.Tensor([1 2 3 4], shape=(4,), dtype=int32) 

tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)
Transmitowane dodawania: A [3, 1] razy [1, 4] daje [3,4]
Dodanie macierzy 3x1 do macierzy 4x1 daje w wyniku macierz 3x4

Oto ta sama operacja bez nadawania:

x_stretch = tf.constant([[1, 1, 1, 1],
                         [2, 2, 2, 2],
                         [3, 3, 3, 3]])

y_stretch = tf.constant([[1, 2, 3, 4],
                         [1, 2, 3, 4],
                         [1, 2, 3, 4]])

print(x_stretch * y_stretch)  # Again, operator overloading
tf.Tensor(
[[ 1  2  3  4]
 [ 2  4  6  8]
 [ 3  6  9 12]], shape=(3, 4), dtype=int32)

W większości przypadków nadawanie jest efektywne zarówno pod względem czasu, jak i przestrzeni, ponieważ operacja nadawania nigdy nie materializuje rozszerzonych tensorów w pamięci.

Widzisz, co wygląda jak nadawanie za pomocą tf.broadcast_to .

print(tf.broadcast_to(tf.constant([1, 2, 3]), [3, 3]))
tf.Tensor(
[[1 2 3]
 [1 2 3]
 [1 2 3]], shape=(3, 3), dtype=int32)

W przeciwieństwie do matematycznego op, na przykład, broadcast_to robi nic specjalnego, aby zapisać w pamięci. Tutaj materializujesz tensor.

Może się to jeszcze bardziej skomplikować. Ten rozdział książki Jake'a VanderPlas za Python Dane Handbook Nauka pokazuje więcej nadawania sztuczki (ponownie w NumPy).

tf.convert_to_tensor

Większość ops, jak tf.matmul i tf.reshape przyjmują argumenty klasy tf.Tensor . Zauważysz jednak, że w powyższym przypadku akceptowane są obiekty Pythona w kształcie tensorów.

Większość, ale nie wszystkie, ops zadzwonić convert_to_tensor na argumenty nie tensorowych. Jest rejestru konwersji, a większość klasy obiektów jak NumPy za ndarray , TensorShape , listy Python i tf.Variable będzie wszystko konwersji automatycznie.

Zobacz tf.register_tensor_conversion_function więcej szczegółów, a jeśli masz swój własny typ chcesz automatycznie konwertować do tensora.

Poszarpane Tensory

Tensor ze zmienną liczbą elementów wzdłuż pewnej osi nazywany jest „postrzępionym”. Zastosowanie tf.ragged.RaggedTensor na poszarpanej danych.

Na przykład This nie może być reprezentowane jako zwykły tensor:

tf.RaggedTensor , kształt: [4, None]
Dwuosiowy postrzępiony tensor, każdy rząd może mieć inną długość.
ragged_list = [
    [0, 1, 2, 3],
    [4, 5],
    [6, 7, 8],
    [9]]
try:
  tensor = tf.constant(ragged_list)
except Exception as e:
  print(f"{type(e).__name__}: {e}")
ValueError: Can't convert non-rectangular Python sequence to Tensor.

Zamiast tworzyć tf.RaggedTensor korzystając tf.ragged.constant :

ragged_tensor = tf.ragged.constant(ragged_list)
print(ragged_tensor)
<tf.RaggedTensor [[0, 1, 2, 3], [4, 5], [6, 7, 8], [9]]>

Kształt tf.RaggedTensor będzie zawierać pewne osie z nieznanymi długościach:

print(ragged_tensor.shape)
(4, None)

Tensory strun

tf.string jest dtype , to znaczy można reprezentować dane jako ciągi (o zmiennej długości tablicami bajtów) w tensorów.

Ciągi są niepodzielne i nie mogą być indeksowane w taki sam sposób, jak ciągi w Pythonie. Długość struny nie jest jedną z osi tensora. Zobacz tf.strings na funkcje nimi manipulować.

Oto skalarny tensor strun:

# Tensors can be strings, too here is a scalar string.
scalar_string_tensor = tf.constant("Gray wolf")
print(scalar_string_tensor)
tf.Tensor(b'Gray wolf', shape=(), dtype=string)

I wektor ciągów:

Wektor ciągów kształt: [3,]
Długość struny nie jest jedną z osi tensora.
# If you have three string tensors of different lengths, this is OK.
tensor_of_strings = tf.constant(["Gray wolf",
                                 "Quick brown fox",
                                 "Lazy dog"])
# Note that the shape is (3,). The string length is not included.
print(tensor_of_strings)
tf.Tensor([b'Gray wolf' b'Quick brown fox' b'Lazy dog'], shape=(3,), dtype=string)

W powyższym wydruku b przedrostek wskazuje, że tf.string dtype nie jest ciągiem znaków Unicode, ale ciąg bajtów. Zobacz Tutorial Unicode Więcej informacji na temat pracy z tekstem Unicode w TensorFlow.

Jeśli przekażesz znaki Unicode, zostaną one zakodowane w UTF-8.

tf.constant("🥳👍")
<tf.Tensor: shape=(), dtype=string, numpy=b'\xf0\x9f\xa5\xb3\xf0\x9f\x91\x8d'>

Niektóre podstawowe funkcje z ciągów można znaleźć w tf.strings , w tym tf.strings.split .

# You can use split to split a string into a set of tensors
print(tf.strings.split(scalar_string_tensor, sep=" "))
tf.Tensor([b'Gray' b'wolf'], shape=(2,), dtype=string)
# ...but it turns into a `RaggedTensor` if you split up a tensor of strings,
# as each string might be split into a different number of parts.
print(tf.strings.split(tensor_of_strings))
<tf.RaggedTensor [[b'Gray', b'wolf'], [b'Quick', b'brown', b'fox'], [b'Lazy', b'dog']]>
Three Struny split, kształt: [3, None]
Dzielenie wielu ciągów znaków zwraca tf.RaggedTensor

I tf.string.to_number :

text = tf.constant("1 10 100")
print(tf.strings.to_number(tf.strings.split(text, " ")))
tf.Tensor([  1.  10. 100.], shape=(3,), dtype=float32)

Chociaż nie można używać tf.cast włączyć tensora ciąg na liczby, można przekształcić go w bajtach, a następnie przetworzony na postać cyfrową.

byte_strings = tf.strings.bytes_split(tf.constant("Duck"))
byte_ints = tf.io.decode_raw(tf.constant("Duck"), tf.uint8)
print("Byte strings:", byte_strings)
print("Bytes:", byte_ints)
Byte strings: tf.Tensor([b'D' b'u' b'c' b'k'], shape=(4,), dtype=string)
Bytes: tf.Tensor([ 68 117  99 107], shape=(4,), dtype=uint8)
# Or split it up as unicode and then decode it
unicode_bytes = tf.constant("アヒル 🦆")
unicode_char_bytes = tf.strings.unicode_split(unicode_bytes, "UTF-8")
unicode_values = tf.strings.unicode_decode(unicode_bytes, "UTF-8")

print("\nUnicode bytes:", unicode_bytes)
print("\nUnicode chars:", unicode_char_bytes)
print("\nUnicode values:", unicode_values)
Unicode bytes: tf.Tensor(b'\xe3\x82\xa2\xe3\x83\x92\xe3\x83\xab \xf0\x9f\xa6\x86', shape=(), dtype=string)

Unicode chars: tf.Tensor([b'\xe3\x82\xa2' b'\xe3\x83\x92' b'\xe3\x83\xab' b' ' b'\xf0\x9f\xa6\x86'], shape=(5,), dtype=string)

Unicode values: tf.Tensor([ 12450  12498  12523     32 129414], shape=(5,), dtype=int32)

tf.string dtype jest stosowany do wszystkich danych surowych bajtów TensorFlow. tf.io moduł zawiera funkcje służące do konwersji danych do i od bajtów tym dekodowanie obrazu i przetwarzania CSV.

Rzadkie tensory

Czasami twoje dane są rzadkie, jak bardzo szeroka przestrzeń do osadzania. TensorFlow obsługuje tf.sparse.SparseTensor i związanych z tym działań, aby efektywnie przechowywać rozrzedzony danych.

tf.SparseTensor , kształt: [3, 4]
Siatka 3x4, z wartościami tylko w dwóch komórkach.
# Sparse tensors store values by index in a memory-efficient manner
sparse_tensor = tf.sparse.SparseTensor(indices=[[0, 0], [1, 2]],
                                       values=[1, 2],
                                       dense_shape=[3, 4])
print(sparse_tensor, "\n")

# You can convert sparse tensors to dense
print(tf.sparse.to_dense(sparse_tensor))
SparseTensor(indices=tf.Tensor(
[[0 0]
 [1 2]], shape=(2, 2), dtype=int64), values=tf.Tensor([1 2], shape=(2,), dtype=int32), dense_shape=tf.Tensor([3 4], shape=(2,), dtype=int64)) 

tf.Tensor(
[[1 0 0 0]
 [0 0 2 0]
 [0 0 0 0]], shape=(3, 4), dtype=int32)