python - 张量流:tf.strings.split()
问题描述
我是 Python 和 AI 的新手。我正在尝试做一个hello world AI。
但我对代码有疑问。路径为“C:\ABC\AAC\data\as001.jpg”|| "C:\ABC\AAC\data\wb001.jpg"
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
import os
import pathlib
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
print(tf.__version__)
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
SIZE = 250
CLASS_NAMES = ['Asparagus','White Bread']
data_dir = pathlib.Path().home().joinpath('Desktop', 'tmp', 'data')
CLASS_NAMES = np.array(['White Bread','Asaparagus'])
list_ds = tf.data.Dataset.list_files(str(data_dir/'*'))
def get_label(path):
parts = tf.strings.split(path, os.path.sep)
# 1. print(parts[-1])
return parts[-1]
def decode_img(img):
img = tf.image.decode_jpeg(img, channels=3)
img = tf.image.convert_image_dtype(img, tf.float32)
img = tf.image.resize(img, [SIZE, SIZE])
return tf.reshape(img, [-1, 250, 250, 3])
def process(path):
label = get_label(path)
img = tf.io.read_file(path)
img = decode_img(img)
return img, label
labeled_ds = list_ds.map(process)
for image, label in labeled_ds:
#2. print(label)
model = Sequential([
Conv2D(16, (3,3), padding='same', activation='relu', input_shape=(SIZE, SIZE, 3)),
MaxPooling2D(2,2),
Dropout(0.2),
Conv2D(32, (3,3), padding='same', activation='relu'),
MaxPooling2D(2,2),
Conv2D(64, (3,3), padding='same', activation='relu'),
MaxPooling2D(2,2),
Dropout(0.2),
Flatten(),
Dense(2, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = model.fit(labeled_ds, epochs = 5, steps_per_epoch = 2)
我试图理解为什么 Print #1 打印 Tensor("strided_slice:0", shape=(), dtype=string) 但 Print #2 打印实际值 tf.Tensor(b'as001.jpg', shape=( ), dtype=字符串)
另外,我正在尝试将值(wb0 到 0 和 as0 到 1)映射到 process 函数,但我似乎无法从 part[-1] 中提取值。
我究竟做错了什么?
任何帮助表示赞赏。
解决方案
短版:使用tf.print
而不是print
.
长版:啊哈-print
在tensorflow
。首先注意还有一个tf.print
. 两者的区别,在于print
构建时不包含在张量流图中,而是tf.print
包含。因此,如果您将您的包装get_label
在@tf.function
装饰器中,print
( #1. print
) 只会在图形构建时打印一次。目前还没有数据tf.Tensor
,所以它只是打印类型。因为您没有将函数包装在 a 中@tf.function
,所以您的函数以急切模式执行。当急切地执行tf.data.Dataset
“管道”(.map
,,,.take
...)时,您(概念上)每次都在构建图形,因此每次都打印空张量的类型。
第二次打印(#2. print
)每次都会打印,因为您是在急切模式下执行的,并且当您tf.Tensor
通过实际数据填充您的 s 时,.map(process)
您可以看到加载的数据。#1
要在执行而不是构建时打印张量,请使用tf.print
而不是print
。
推荐阅读
- javascript - 单击拖动和onClick反应?
- javascript - GraphQL 突变后 SetState 不起作用
- javascript - 如何编码'DOM方法的ID以在递归中使用'?
- typescript - 交叉点类型不能正常工作?
- javascript - 在旧网站上 Gulp 到 Webpack 迁移 - 从非 npm 依赖项生成供应商
- xpath - 选择属性值时 XPath 和 XQuery 的区别
- c++ - 当行和列由用户设置时,2D x 2D,随机
- mysql - 最新的记录正在进入 mysql 的第一行
- javascript - Javascript函数中的动态参数
- python - 如何在 Grakn 中使用 Python 客户端计算连接组件