首页 > 解决方案 > 张量流: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] 中提取值。

我究竟做错了什么?

任何帮助表示赞赏。

标签: pythontensorflow

解决方案


短版:使用tf.print而不是print.

长版:啊哈-printtensorflow。首先注意还有一个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


推荐阅读