Это 16-й день моего участия в августовском испытании обновлений. Узнайте подробности события:Испытание августовского обновления
Сессия Управление конференцией
Session — это оператор выполнения TensorFlow для управления и вывода файла, запустите Session.run(), чтобы получить результат операции, которую вы хотите
import tensorflow as tf
# session 会议控制
tf.compat.v1.disable_eager_execution() # 保证sess.run()能够正常运行
matrix1 = tf.constant([[3, 3]]) # 建立两个矩阵
matrix2 = tf.constant([[2], [2]])
product = tf.matmul(matrix1, matrix2) # 矩阵乘法-->np.dot(m1,m2)
# 方法一
sess = tf.compat.v1.Session()
result = sess.run(product)
print(result) # 12 矩阵相乘的结果
sess.close()
# 方法二
# with tf.compat.v1.Session() as session: # 自动关上的
# result = session.run(product)
# print(result)
Определение переменной переменной
import tensorflow as tf
tf.compat.v1.disable_eager_execution()
state = tf.Variable(0,name='counter') # Variable 变量
# print(state.name) # result=counter:0
one = tf.constant(1) # 加上常量
new_value = tf.add(state,one)
update = tf.compat.v1.assign(state, new_value) # 更新这个变量的值
init = tf.compat.v1.global_variables_initializer() # 更新过了之后就会这么一个函数的进行,初始化所有变量才能激活这些变量
with tf.compat.v1.Session() as sess:
sess.run(init)
for _ in range(3):
sess.run(update) # 每一次都更新这个函数里面的值
print(sess.run(state)) # 这样才会有这个state的出现,不然打印不出来的,要必须先在这个里面变成
# 1
# 2
# 3
Ввод элемента управления заполнителем
import tensorflow as tf
# input1 = tf.compat.v1.placeholder(tf.float32,[2,2]) # [2,2] 输入两行两列的数据
tf.compat.v1.disable_eager_execution()
input1 = tf.compat.v1.placeholder(tf.float32)
input2 = tf.compat.v1.placeholder(tf.float32)
output = tf.compat.v1.multiply(input1, input2) # 相乘
with tf.compat.v1.Session() as sess:
print(sess.run(output, feed_dict={input1: [7.], input2: [2.]})) # 14
Activation_Function функция активации
Activation_Function Функция активации используется для добавления нелинейных факторов для решения проблем, которые не могут быть решены с помощью линейных моделей.
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
tf.compat.v1.disable_eager_execution()
def add_layer(inputs, in_size, out_size,n_layer, activation_function):
# 添加隐藏层 即使添加神经层数 以达到不断迭代的过程
layer_name = 'layer%s'% n_layer
with tf.name_scope(layer_name):
with tf.name_scope('weights'):
Weights = tf.Variable(tf.random.normal([in_size, out_size]), name='W') # 定义一个矩阵,随机定义参数,初始值
tf.summary.histogram(layer_name+'/weights',Weights)
with tf.name_scope('biases'):
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b') # biases 的初始值是推荐不要为零,所以现在就是要加上0.1
tf.summary.histogram(layer_name+'/biases',biases)
with tf.name_scope('Wx_plus_b'):
Wx_plus_b = tf.compat.v1.matmul(inputs, Weights,name='wb') + biases # input*Weights + biases 这是预测的值 还没激活
if activation_function is None:
outputs = Wx_plus_b # 这个是线性方程,所以就不需要加上非线性的激活函数
else:
outputs = activation_function(Wx_plus_b)
tf.summary.histogram(layer_name+'/outputs',outputs)
return outputs
x_data = np.linspace(-1, 1, 300)[:, np.newaxis].astype(np.float32) # 建立一个-1 1 的等差数列 最后加上一个维度,变成有维度的矩阵形式
# 现在是[300,1] 的矩阵 输入层 300行1列的矩阵
# x_data=tf.cast(tf.float32,x_data)
noise = np.random.normal(0, 0.05, x_data.shape) # 手动添加噪点 方差0.05
# noise=tf.cast(tf.float32,noise)
y_data = np.square(x_data) - 0.5 + noise
# y_data=tf.cast(tf.float32,y_data)
with tf.name_scope('input'): # 输入层
xs = tf.compat.v1.placeholder(tf.float32, [None, 1], name='x_input') # 这里是传入数据用的,这里无论是传入多少个例子都是可以的
ys = tf.compat.v1.placeholder(tf.float32, [None, 1], name='y_input') # 这里是一个None来表达 ,但是是一个矩阵的形式:未知行1列
l1 = add_layer(xs, 1, 10, 1, tf.nn.relu)
# 这里是添加了第一层的隐藏层[1,10] 这里是1行10列的矩阵
predition = add_layer(l1, 10, 1, 2, None)
# 最后的输出层是一个[10,1] 是一个10行1列的矩阵
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - predition), axis=1)) # 平均的误差
tf.summary.scalar('loss', loss)
with tf.name_scope('train'):
train_step = tf.compat.v1.train.GradientDescentOptimizer(0.1).minimize(loss)
# 学习效率0.1 用这个优化器以0.1的效率对这个误差进行更正
init = tf.compat.v1.global_variables_initializer()
# 随机的梯度下降
fig = plt.figure() # 先生成一个框框
ax = fig.add_subplot(1, 1, 1)
ax.scatter(x_data, y_data) # 生成原来的图片
plt.ion()
plt.show()
with tf.compat.v1.Session() as sess:
writer = tf.compat.v1.summary.FileWriter("logs/", sess.graph)
sess.run(init)
for i in range(1000):
sess.run(train_step, feed_dict={xs: x_data, ys: y_data}) # 方便封装
if i % 50 == 0:
# print(sess.run(loss, feed_dict={xs: x_data, ys: y_data}))
try:
ax.lines.remove(lines[0]) # 显示之后要去除掉那条线
except Exception: # 第一次是没有的,
pass
predition_value = sess.run(predition, feed_dict={xs: x_data, ys: y_data})
lines = ax.plot(x_data, predition_value, 'r-', lw=5) # 将预测的这个值打上去
plt.pause(0.1)
# loss_function不断在减小,所以就会一直在学习,减少误差
# 1.9184123
# 0.053955305
# 0.03053456
# 0.017190851
# 0.010993273
# 0.008209449
# 0.0067526144
# 0.0058726957
# 0.005269445
# 0.00477808
# 0.0044394922
# 0.0041766805
# 0.0039696493
# 0.003815
# 0.0036952242
# 0.0036034652
# 0.0035240129
# 0.0034543637
# 0.0033897285
# 0.0033306282
# Tips:空间不足的时候,有可能会报错的
TensorBorad
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
tf.compat.v1.disable_eager_execution()
def add_layer(inputs, in_size, out_size, n_layer, activation_function): # 添加隐藏层 即使添加神经层数 以达到不断迭代的过程吧
layer_name = 'layer%s' % n_layer
with tf.name_scope(layer_name):
with tf.name_scope('weights'):
Weights = tf.Variable(tf.random.normal([in_size, out_size]), name='W') # 定义一个矩阵,随机定义参数,初始值
tf.summary.histogram(layer_name + '/weights', Weights)
with tf.name_scope('biases'):
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b') # biases 的初始值是推荐不要为零,所以现在就是要加上0.1
tf.summary.histogram(layer_name + '/biases', biases)
with tf.name_scope('Wx_plus_b'):
Wx_plus_b = tf.compat.v1.matmul(inputs, Weights, name='wb') + biases # input*Weights + biases 这是预测的值 还没激活
if activation_function is None:
outputs = Wx_plus_b # 这个是线性方程,所以就不需要加上非线性的激活函数
else:
outputs = activation_function(Wx_plus_b)
tf.summary.histogram(layer_name + '/outputs', outputs)
return outputs
x_data = np.linspace(-1, 1, 300)[:, np.newaxis].astype(np.float32) # 建立一个-1 1 的等差数列 最后加上一个维度,变成有维度的矩阵形式
# 现在是[300,1] 的矩阵 输入层 300行1列的矩阵
# x_data=tf.cast(tf.float32,x_data)
noise = np.random.normal(0, 0.05, x_data.shape) # 手动添加噪点 方差0.05
# noise=tf.cast(tf.float32,noise)
y_data = np.square(x_data) - 0.5 + noise
# y_data=tf.cast(tf.float32,y_data)
with tf.name_scope('input'): # 输入层
xs = tf.compat.v1.placeholder(tf.float32, [None, 1], name='x_input') # 这里是传入数据用的,这里无论是传入多少个例子都是可以的
ys = tf.compat.v1.placeholder(tf.float32, [None, 1], name='y_input') # 这里是一个None来表达 ,但是是一个矩阵的形式:未知行1列
l1 = add_layer(xs, 1, 10, 1, tf.nn.relu)
# 这里是添加了第一层的隐藏层[1,10] 这里是1行10列的矩阵
predition = add_layer(l1, 10, 1, 2, None)
# 最后的输出层是一个[10,1] 是一个10行1列的矩阵
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys - predition), axis=1)) # 平均的误差
tf.summary.scalar('loss', loss)
with tf.name_scope('train'):
train_step = tf.compat.v1.train.GradientDescentOptimizer(0.1).minimize(loss)
# 学习效率0.1 用这个优化器以0.1的效率对这个误差进行更正
init = tf.compat.v1.global_variables_initializer()
with tf.compat.v1.Session() as sess:
writer = tf.compat.v1.summary.FileWriter("logs/", sess.graph)
sess.run(init)
merged = tf.compat.v1.summary.merge_all()
for i in range(1000):
sess.run(train_step, feed_dict={xs: x_data, ys: y_data}) # 方便封装
if i % 50 == 0:
result = sess.run([merged,train_step], feed_dict={xs: x_data, ys: y_data})
writer.add_summary(result, i)
# Tips:空间不足的时候,有可能会报错的
Классификатор классификации
Пример распознавания рукописных цифр
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist_data = input_data.read_data_sets("MNIST_data/", one_hot=True)
def add_layer(inputs, in_size, out_size, activation_function): # 添加隐藏层 即使添加神经层数 以达到不断迭代的过程吧
Weights = tf.Variable(tf.random.normal([in_size, out_size]), name='W') # 定义一个矩阵,随机定义参数,初始值
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b') # biases 的初始值是推荐不要为零,所以现在就是要加上0.1
Wx_plus_b = tf.compat.v1.matmul(inputs, Weights, name='wb') + biases
# input*Weights + biases 这是预测的值 还没激活
if activation_function is None:
outputs = Wx_plus_b # 这个是线性方程,所以就不需要加上非线性的激活函数
else:
outputs = activation_function(Wx_plus_b)
return outputs
def compute_accracy(v_xs, v_ys):
global prediction
y_pre = sess.run(prediction, feed_dict={xs: v_xs})
corrent_prediction = tf.equal(tf.argmax(y_pre, 1), tf.argmax(v_ys, 1)) # 生成预测值
accuracy = tf.reduce_mean(tf.cast(corrent_prediction, tf.float32))
result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys})
return result
tf.compat.v1.disable_eager_execution()
xs = tf.compat.v1.placeholder(tf.float32, [None, 784]) # 28*28
ys = tf.compat.v1.placeholder(tf.float32, [None, 10])
prediction = add_layer(xs, 784, 10, activation_function=tf.nn.softmax)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.math.log(prediction), axis=1)) # 交叉熵损失函数
train_step = tf.compat.v1.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
sess = tf.compat.v1.Session()
sess.run(tf.compat.v1.initialize_all_variables())
for i in range(1000):
batch_xs, batch_ys = mnist_data.train.next_batch(100)
sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys}) # 进行学习1000次
if i % 50 == 0:
print(compute_accracy(mnist_data.test.images, mnist_data.test.labels))
sess.close()
Overfitting
Он хорошо работает в тренировочном наборе, но хорошо работает и в тестовом наборе.Например, он очень силен в своем собственном круге, но очень водянист, когда его помещают в другое место.
Переоснащение
1. Увеличьте объем данных, пока круг достаточно велик, явление переоснащения может быть уменьшено.
2. Используйте нормализацию, y=w*x+b
Нормализация L1:
Регуляризация L2:
L3-->Куб
Регуляризация отсева: случайным образом отбрасываем в него нейроны, чтобы обучение не зависело от этих нейронов.
Сверточная нейронная сеть CNN
Сжать изображение RGB, уменьшить длину и ширину изображения и увеличить высоту.
Наконец, превратите толщину в классификатор.
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
mnist_data = input_data.read_data_sets("MNIST_data/", one_hot=True)
graph = tf.compat.v1.get_default_graph()
tf.compat.v1.disable_eager_execution()
xs = tf.compat.v1.placeholder(tf.float32, [None, 784]) # 28*28
ys = tf.compat.v1.placeholder(tf.float32, [None, 10])
keep_prob = tf.compat.v1.placeholder(tf.float32)
x_image = tf.reshape(xs, [-1, 28, 28, 1]) # 像素点 28*28 黑白的所以通道数就是为1
# print(x_image.shape) # [n_smaples,28,28,1]
def add_layer(inputs, in_size, out_size, activation_function): # 添加隐藏层 即使添加神经层数 以达到不断迭代的过程吧
Weights = tf.Variable(tf.random.normal([in_size, out_size]), name='W') # 定义一个矩阵,随机定义参数,初始值
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, name='b') # biases 的初始值是推荐不要为零,所以现在就是要加上0.1
Wx_plus_b = tf.compat.v1.matmul(inputs, Weights, name='wb') + biases # input*Weights + biases 这是预测的值 还没激活
if activation_function is None:
outputs = Wx_plus_b # 这个是线性方程,所以就不需要加上非线性的激活函数
else:
outputs = activation_function(Wx_plus_b)
return outputs
def compute_accracy(v_xs, v_ys):
global prediction
y_pre = sess.run(prediction, feed_dict={xs: v_xs, keep_prob: 1})
corrent_prediction = tf.equal(tf.argmax(y_pre, 1), tf.argmax(v_ys, 1)) # 生成预测值
accuracy = tf.reduce_mean(tf.cast(corrent_prediction, tf.float32))
result = sess.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1})
return result
# 初始化weight bias
def weight_variable(shape):
initial = tf.compat.v1.truncated_normal(shape, stddev=0.1) # stddev标准差
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.compat.v1.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W): # strides=[batchsize,宽,高,通道数]
# [1,x_movement,y_movement,1]
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME') # 2维的CNN 三层的跨度都是1
def max_pool_2x2(x):
# [1,x_movement,y_movement,1]
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') #
## conv1 layer
W_conv1 = weight_variable([5, 5, 1, 32]) # patch 5*5的像素, in_size 1 一个单位的结果,out_size 32 的高度
b_conv1 = bias_variable([32])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1) # 类似y=w*x+b 加relu实现非线性化 outsize=28*28*32
h_pool1 = max_pool_2x2(h_conv1) # outsize=14*14*32 SAME是指像素/步长
## conv2 layer
W_conv2 = weight_variable([5, 5, 32, 64]) # 不断变高变厚
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2) # 类似y=w*x+b 加relu实现非线性化 outsize=14*14*64
h_pool2 = max_pool_2x2(h_conv2) # outsize=7*7*64
## func1 layer
W_fc1 = weight_variable([7 * 7 * 64, 1024]) # 变得更高更宽 1024自己定义 1024个神经元
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
# 将h_pool2原来的形状由[n_samples,7,7,64]---->[n_samples,7*7*64]的形状 展平 降维
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
f_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
## func2 layer
W_fc2 = weight_variable([1024, 10]) # 变得更高更宽 1024自己定义 1024个神经元
b_fc2 = bias_variable([10])
prediction = tf.nn.softmax(tf.nn.relu(tf.matmul(f_fc1_drop, W_fc2) + b_fc2))
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.math.log(prediction), axis=1)) # 交叉熵损失函数
train_step = tf.compat.v1.train.AdamOptimizer(1e-4).minimize(cross_entropy)
# 这样配置GPU才不会爆出内存不足
gpu_no = '0' # or '1'
os.environ["CUDA_VISIBLE_DEVICES"] = gpu_no
# 定义TensorFlow配置
config = tf.compat.v1.ConfigProto()
# 配置GPU内存分配方式,按需增长,很关键
config.gpu_options.allow_growth = True
# 配置可使用的显存比例
config.gpu_options.per_process_gpu_memory_fraction = 0.1
# 在创建session的时候把config作为参数传进去
sess = tf.compat.v1.InteractiveSession(config=config)
sess.run(tf.compat.v1.initialize_all_variables())
for i in range(1000):
batch_xs, batch_ys = mnist_data.train.next_batch(100)
sess.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: 0.5})
if i % 50 == 0:
print(compute_accracy(mnist_data.test.images, mnist_data.test.labels))
sess.close()
Сохранить сохранение извлечения
![IMG_0784](D:\294350394\FileRecv\MobileFile\IMG_0784.PNG)import tensorflow as tf
import numpy as np
tf.compat.v1.disable_eager_execution()
# W = tf.Variable([[1, 2, 3], [3, 4, 5]], dtype=tf.float32, name='weights')
# b = tf.Variable([[1, 2, 3]], dtype=tf.float32, name='biases')
# init = tf.compat.v1.initialize_all_variables()
# saver = tf.compat.v1.train.Saver()
# with tf.compat.v1.Session() as sess:
# sess.run(init)
# save_path = saver.save(sess,"my_net/save_net.ckpt")
# print("Save to path:",save_path)
W = tf.Variable(np.arange(6).reshape((2, 3)), dtype=tf.float32, name='weights')
b = tf.Variable(np.arange(3).reshape((1, 3)), dtype=tf.float32, name='biases')
saver =tf.compat.v1.train.Saver()
with tf.compat.v1.Session() as sess:
saver.restore(sess,"my_net/save_net.ckpt")
print("weights:",sess.run(W))
print("biases:",sess.run(b))
#weights: [[1. 2. 3.] 这里的就是上面存出的矩阵
# [3. 4. 5.]]
#biases: [[1. 2. 3.]]
Рекуррентная нейронная сеть RNN
Усиленные нейронные сети
Каждый выход является кратким изложением предыдущего и запоминает предыдущее содержимое.
Это должно превратить это в суперпозицию предыдущего контента со временем.В соответствии с порядком времени каждый выход будет иметь память о предыдущем.
В процессе цикла, если он
Возможно, что при этой ошибке > 1 будет происходить процесс непрерывного накопления, что приведет к взрыву градиента.
При переходе назад не перейдет в исходное состояние (процесс деривации цепочки)
Чтобы решить некоторые из этих проблем:
LSTMМодель(Долговременная кратковременная память:
Блок ворот используется для управления типом входа стеллажа, записывать ли этот момент в это время.
Пиши, чтобы писать, Читай, чтобы читать, Забудь, чтобы забыть главное.
Это делается для того, чтобы сюжет разделенной линии не влиял на сюжет основной линии и, наконец, на HappyEnd или BadEnd.
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
mnist_data = input_data.read_data_sets("MNIST_data/", one_hot=True)
graph = tf.compat.v1.get_default_graph()
tf.compat.v1.disable_eager_execution()
lr = 0.001
training_iters = 10000
batch_size = 128
display_step = 10
n_input = 28 # MNIST data的输入
n_step = 28 # 时间的间隔
n_hidden_unis = 128 # 隐藏层神经元的个数
n_classes = 10 # MNIST 里面的个数(0-9数字类型)
x = tf.compat.v1.placeholder(tf.float32, [None, n_step, n_input]) # 28*28
y = tf.compat.v1.placeholder(tf.float32, [None, n_classes])
keep_prob = tf.compat.v1.placeholder(tf.float32)
weights = {
'in': tf.Variable(tf.random.normal([n_input, n_hidden_unis])), # (28,128)
'out': tf.Variable(tf.random.normal([n_hidden_unis, n_classes])) # (128,10)
}
biases = {
'in': tf.Variable(tf.constant(0.1, shape=[n_hidden_unis, ])), # (128,)
'out': tf.constant(0.1, shape=[n_classes, ]) # (10,)
}
def RNN(X, weights, biases):
# 隐藏层所输入的结构
# X(128 batch,28 step,28 input)
# ==>(128*28,28 input)
X = tf.reshape(X, [-1, n_input])
# X_in ==> (128batch * 28 steps,128 hidden)
X_in = tf.matmul(X, weights['in']) + biases['in']
# X_in ==> (128batch , 28steps, 128 hidden)
X_in = tf.reshape(X_in, [-1, n_step, n_hidden_unis])
# cell
lstm_cell = tf.compat.v1.nn.rnn_cell.BasicLSTMCell(n_hidden_unis, forget_bias=1.0, state_is_tuple=True)
# (c_state,m_state)# c_state主线剧情,m_state 分线剧情.
_init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
outputs, states = tf.compat.v1.nn.dynamic_rnn(lstm_cell, X_in, initial_state=_init_state, time_major=False)
# outputs 是一个list
results = tf.matmul(states[1], weights['out']) + biases['out'] # states[1] 是分线剧情的结果 states[0] 是主线剧情的结果
return results
prediction = RNN(x, weights, biases)
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(prediction, y)) # 交叉熵损失函数
train_op = tf.compat.v1.train.AdamOptimizer(lr).minimize(cross_entropy)
correct_pred = tf.equal(tf.argmax(prediction, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
# 这样配置GPU才不会爆出内存不足
gpu_no = '0' # or '1'
os.environ["CUDA_VISIBLE_DEVICES"] = gpu_no
# 定义TensorFlow配置
config = tf.compat.v1.ConfigProto()
# 配置GPU内存分配方式,按需增长,很关键
config.gpu_options.allow_growth = True
# 配置可使用的显存比例
config.gpu_options.per_process_gpu_memory_fraction = 0.1
# 在创建session的时候把config作为参数传进去
sess = tf.compat.v1.InteractiveSession(config=config)
sess.run(tf.compat.v1.initialize_all_variables())
step = 0
while step * batch_size < training_iters:
batch_xs, batch_ys = mnist_data.train.next_batch(batch_size)
batch_xs = batch_xs.reshape([batch_size, n_step, n_input]) # 28*28
sess.run([train_op], feed_dict={
x: batch_xs,
y: batch_ys
})
if step % 20 == 0:
print(sess.run(accuracy, feed_dict={
x: batch_xs,
y: batch_ys
}))
sess.close()
Автоэнкодер (обучение без учителя)
Процесс сжатия и распаковки изображений также называется неконтролируемым обучением, потому что это необходимо для предотвращения того, чтобы информация, которую необходимо обработать, была слишком большой и вызывала медленное чтение.
Вышеприведенное изображение похоже на это, обычно нужны только данные X слева, кодировать сжатие, декодировать декомпрессию
Вышеизложенное — это то, что я узнал о ТФ на текущем этапе.