首页 > 编程问答 >“tuple”对象没有属性“rank”

“tuple”对象没有属性“rank”

时间:2024-07-23 04:25:54浏览次数:7  
标签:python keras tensorflow2.0 tensor tf.keras

这是一个 FabricNet 示例实现(官方代码)。正如研究论文中所述,输入图像尺寸为 120x120x3。我尝试了下面的代码,但它抛出错误“tuple”对象没有属性“rank”。这是输入形状的打印结果:第0层输入形状:(None, 8, 8, 728)。它显然是一个元组,但模型需要一个张量。同一问题的答案之一提到使用 tf.constant(res) 将其转换为 Numpy 数组。但它随后抛出错误;

A KerasTensor is symbolic; it's a placeholder for a shape or dtype. It doesn't have any actual numerical value. You cannot convert it to a NumPy array.
import cv2
import numpy as np
from sklearn.model_selection import train_test_split
import tensorflow as tf
from tensorflow.python.keras.layers import *
import matplotlib.pyplot as plt

def load_data_from_txt(txt_file, image_size=(120, 120)):
    image_paths = []
    labels = []
    
    with open(txt_file, 'r') as f:
        for line in f:
            path, label = line.strip().split(', ')
            image_paths.append(path)
            labels.append(int(label))
    
    images = []
    for path in image_paths:
        try:
            img = cv2.imread(path)
            if img is None:
                print(f"Warning: Unable to read image at {path}")
                continue
            img = cv2.resize(img, image_size)  # Resize to desired size
            images.append(img)
        except Exception as e:
            print(f"Error processing {path}: {e}")
            continue
    
    if len(images) == 0:
        raise ValueError("No images were loaded. Check the file paths.")
    
    images = np.array(images, dtype=np.float32) / 255.0  # Normalize images
    labels = np.array(labels[:len(images)])  # Ensure labels match the number of loaded images
    
    return images, labels

# Load data
x_data, y_data = load_data_from_txt('FISR.txt')
print(f"x_data shape: {x_data.shape}")

# Split data into training and testing sets
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.25, stratify=y_data)

# One-hot encode labels
num_classes = 7 

y_train = tf.one_hot(np.squeeze(y_train), depth=7).numpy()
y_test = tf.one_hot(np.squeeze(y_test), depth=7).numpy()

def parser(tok, id, cls):
    ''' 
    SepConv: S,f,k,s
    MaxPool: P,s
    ReLU   : R
    Dropout: D
    '''
    print(f"Parsing token: {tok}")
 
    if tok[0] == 'S':
        filters, ks, stride = list(map(int, tok[1:].split(',')))
        print(f"Creating SeparableConv2D with filters={filters}, kernel_size={ks}, strides={stride}")

        return SeparableConv2D(filters=filters, kernel_size=ks, strides=stride, padding='same', name=f'sepconv2d_d{id}_c{cls}')
    
    elif tok[0] == 'P':
        print(f"Creating MaxPool2D with pool_size={int(tok[1:])}")
        return MaxPool2D(pool_size=int(tok[1:]), name=f'MaxPool2D_d{id}_c{cls}')
    
    elif tok[0] == 'R':
        print("Creating ReLU")
        return ReLU(name=f'ReLU_d{id}_c{cls}')
    
    elif tok[0] == 'D':
        print("Creating Dropout with rate=0.1")
        return Dropout(0.1, name=f'dropout_d{id}_c{cls}')
    
    elif tok[0] == 'N':
        print("Creating BatchNormalization")
        return BatchNormalization()
    else:
        print('Invalid')


# How to define ensemble structure:
# S: SeparableConv2D, follows by filter, kernel, and stride 
#    example: S64,3,2
# P: MaxPool, followed by pool size
#    example: P2
# R: ReLU activation
# D: Dropout, defaults to 0.1 drop
#
# A full example: 'S8,3,2_R_D_S8,3,2_R_D'
# The network is as follows:
#    SeparableConv2D(filters=8, kernel_size=3, strides=2)
#    ReLU()
#    Dropout(0.1)
#    SeparableConv2D(filters=8, kernel_size=3, strides=2)
#    ReLU()
#    Dropout(0.1)


ensemble_structure = ['S64,3,2_R_D_S64,3,2_R_D',
                      'S32,3,2_R_D_S64,3,2_R_D',
                      'S16,3,2_R_D_S32,3,2_R_D', 
                      'S8,3,2_R_D_S8,3,2_R_D',
                      'S4,3,2_S16,3,2']


def Xception_block(input_shape, classes,
                   activation='sigmoid',
                   flows=7, 
                   ensemble='S4,3,2_S16,3,2',
                   loss='binary_crossentropy',
                   learning_rate=0.001,
                   weights='imagenet'):

    '''
    input_shape : input shape of image
    classes     : number of classes 
    breakindex  : number of xception block-flows to be used 
    ensemble    : the default ensemble model to be followed for each class
    '''

    assert flows > 0 and flows < 10, "The number of flows should be between [1-9]"
    assert loss in ['binary_crossentropy', 'categorical_crossentropy'], "loss can be either 'binary_crossentropy' or 'categorical_crossentropy'"

    tf.keras.backend.clear_session()
    breakindex = [36, 46, 56, 66, 76, 86, 96, 106, 116]
    
    input_img = tf.keras.Input(input_shape, name='input')
    base_model = tf.keras.applications.Xception(input_tensor=input_img, 
                                                include_top=False, 
                                                weights=weights)
    
    totLayers = len(base_model.layers)
    # for i in range(totLayers):
    #     base_model.layers[i+1]._name += '_head'

    # Last index of the head CNN
    comb_out = base_model.layers[breakindex[flows-1]].output
    #base_model.layers[breakindex[flows-1]]._name += '_lastcom'

    seps = []
    if ensemble != '':
        esets = ensemble.split('_')
        print('esets:', esets)
    else:
        esets = None

    for seg in range(classes):
        if esets != None:
            res = comb_out
            past = None
            for i, tok in enumerate(esets):
                print(f"Layer {i} type: {tok[0]}")
                print(f"Layer {i} input shape: {res.shape}")
                conv_layer = parser(tok, i, seg)
               
                res = conv_layer(res)
                print(f"Layer {i} output shape: {res.shape}")
                if 'S' in tok and past != None and res.shape[-1] == past.shape[-1]:
                    res = Add()([res, past])
                    print('Residual added')
                if 'S' in tok:
                    past = res
        else:
            res = SeparableConv2D(filters=16, kernel_size=3, 
                                  strides=2, name=f'sepconv2d_d1_c{seg}')(comb_out)
            res = ReLU(name=f'maxpool2d_d1_c{seg}')(res)
            res = SeparableConv2D(filters=8, kernel_size=3, strides=2, name=f'sepconv2d_d2_c{seg}')(res)
            res = ReLU(name=f'maxpool2d_d2_c{seg}')(res)

        res = Flatten(name='flatten_'+str(seg))(res)
        res = Dense(1)(res)
        seps.append(res)
        
    out = Concatenate()(seps)
    out = Activation('sigmoid' if loss=='binary_crossentropy' else 'softmax')(out)    
    model = tf.keras.Model(input_img, out)

    print('Params', model.count_params())

    model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate), 
                  loss=loss,
                  metrics=[tf.keras.metrics.CategoricalAccuracy(),
                           tf.keras.metrics.BinaryAccuracy(),
                           tf.keras.metrics.Precision(),
                           tf.keras.metrics.Recall(),
                           tf.keras.metrics.TopKCategoricalAccuracy(),
                           tf.keras.metrics.AUC(num_thresholds=200,
                                                multi_label=True),
                           tf.keras.metrics.TruePositives(),
                           tf.keras.metrics.FalsePositives(),
                           ],
                  )
    
    return model

model = Xception_block(x_train.shape[1:], 7,
                       flows=1, ensemble=ensemble_structure[-1],
                       loss='categorical_crossentropy')

model.summary()

#tf.keras.utils.plot_model(model, to_file="model.png",show_shapes=True, 
#                          show_layer_names=True, dpi=96)

history = model.fit(x_train, y_train, validation_data=(x_test, y_test), 
                    epochs=10,
                    callbacks=[tf.keras.callbacks.EarlyStopping(monitor='val_loss', 
                                                                patience=3,
                                                                restore_best_weights=True)])

epochs = np.arange(1, len(history.history['loss'])+1)

plt.plot(epochs, history.history['loss'], label='loss')
plt.plot(epochs, history.history['auc'], label='auc')
plt.plot(epochs, history.history['precision'], label='precision')
plt.plot(epochs, history.history['recall'], label='recall')


plt.xlabel('Epochs')
plt.ylabel('Metric')
plt.grid()
plt.legend()
plt.show()

plt.plot(epochs, history.history['val_loss'], label='val_loss')
plt.plot(epochs, history.history['val_auc'], label='val_auc')
plt.plot(epochs, history.history['val_precision'], label='val_precision')
plt.plot(epochs, history.history['val_recall'], label='val_recall')

plt.xlabel('Epochs')
plt.ylabel('Metric')
plt.grid()
plt.legend()
plt.show()

我尝试使用“tf.constant(res)”将第 0 层输入形状转换为 numpy 数组,但它不起作用。所以我删除了那部分。当我运行代码时,它抛出了他的错误;

libpng error: IDAT: CRC error
Warning: Unable to read image at Fabrics/Cotton/1221/im_4.png
x_data shape: (2212, 120, 120, 3)
esets: ['S4,3,2', 'S16,3,2']
Layer 0 type: S
Layer 0 input shape: (None, 8, 8, 728)
Parsing token: S4,3,2
Creating SeparableConv2D with filters=4, kernel_size=3, strides=2
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File /Users/wadugekaveeshakavindifernando/Documents/fyp/FabricNet/fabricnet.py:209
    193     model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=learning_rate), 
    194                   loss=loss,
    195                   metrics=[tf.keras.metrics.CategoricalAccuracy(),
   (...)
    204                            ],
    205                   )
    207     return model
--> 209 model = Xception_block(x_train.shape[1:], 7,
    210                        flows=1, ensemble=ensemble_structure[-1],
    211                        loss='categorical_crossentropy')
    213 model.summary()
    215 #tf.keras.utils.plot_model(model, to_file="model.png",show_shapes=True, 
    216 #                          show_layer_names=True, dpi=96)

File /Users/wadugekaveeshakavindifernando/Documents/fyp/FabricNet/fabricnet.py:169
    166 print(f"Layer {i} input shape: {res.shape}")
    167 conv_layer = parser(tok, i, seg)
--> 169 res = conv_layer(res)
    170 print(f"Layer {i} output shape: {res.shape}")
    171 if 'S' in tok and past != None and res.shape[-1] == past.shape[-1]:

File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/tensorflow/python/keras/engine/base_layer.py:1026, in Layer.__call__(self, *args, **kwargs)
...
    231                      ', found ndim=' + str(ndim) +
    232                      '. Full shape received: ' +
    233                      str(tuple(shape)))

AttributeError: 'tuple' object has no attribute 'rank'

该错误 "'tuple' 对象没有属性 'rank'" 出现在你尝试将一个 Keras 张量( res )传递给需要一个 NumPy 数组作为输入的层时。这通常发生在你试图在 Keras 模型的定义中混合使用符号张量操作和急切执行操作时。

以下是导致此错误的原因以及如何修复该错误:

  1. Keras 张量与 NumPy 数组: Keras 张量是符号的,这意味着它们代表着计算图中的节点,而不是包含具体值的数组。另一方面,NumPy 数组包含数值数据,你可以直接在上面执行操作。

  2. 混合急切执行和图执行: 在你的代码中,你似乎在 Keras 的图执行模式下(这是 Keras 模型的默认模式)工作。在图执行中,操作会先被定义,然后在稍后才会执行。然而,当你调用 res.shape[-1] 时,你正在尝试在一个符号张量上执行急切执行操作。这就是导致错误的原因。

解决方案:

要解决此问题,你需要确保在定义 Keras 模型时一直使用符号张量操作。这意味着避免在模型定义中使用任何依赖于张量具体值的 NumPy 函数或属性(例如 .shape .rank 、切片等)。

以下是针对你的代码的一些具体修改建议:

  • 使用 tf.shape 获取符号张量形状: 不要使用 res.shape[-1] ,而是使用 tf.shape(res)[-1] tf.shape 函数返回一个表示张量形状的符号张量。

  • 避免在模型定义中使用 NumPy 函数: 确保在模型定义中使用的所有函数都是 Keras 层、张量操作或与 TensorFlow 兼容的其他函数。

以下是修改后的 parser 函数代码:

def parser(tok, id, cls):
    ''' 
    SepConv: S,f,k,s
    MaxPool: P,s
    ReLU   : R
    Dropout: D
    '''
    print(f"Parsing token: {tok}")

    if tok[0] == 'S':
        filters, ks, stride = list(map(int, tok[1:].split(',')))
        print(f"Creating SeparableConv2D with filters={filters}, kernel_size={ks}, strides={stride}")

        return SeparableConv2D(filters=filters, kernel_size=ks, strides=stride, padding='same', name=f'sepconv2d_d{id}_c{cls}')

    elif tok[0] == 'P':
        print(f"Creating MaxPool2D with pool_size={int(tok[1:])}")
        return MaxPool2D(pool_size=int(tok[1:]), name=f'MaxPool2D_d{id}_c{cls}')

    elif tok[0] == 'R':
        print("Creating ReLU")
        return ReLU(name=f'ReLU_d{id}_c{cls}')

    elif tok[0] == 'D':
        print("Creating Dropout with rate=0.1")
        return Dropout(0.1, name=f'dropout_d{id}_c{cls}')

    elif tok[0] == 'N':
        print("Creating BatchNormalization")
        return BatchNormalization()
    else:
        print('Invalid')

通过进行这些更改,你应该可以解决 "'tuple' 对象没有属性 'rank'" 错误,并确保你的 Keras 模型能够正确定义和训练。

标签:python,keras,tensorflow2.0,tensor,tf.keras
From: 78779580

相关文章

  • 无法在 python 中安装 pip install expliot - bluepy 的 Building Wheel (pyproject.t
    在此处输入图像描述当我尝试在Windows计算机中通过cmd安装pipinstallexpliot包时,我收到2个错误名称×Buildingwheelforbluepy(pyproject.toml)didnotrunsuccessfully.│exitcode:1**AND**opt=self.warn_dash_deprecation......
  • python 用单斜杠-反斜杠替换url字符串中的双斜杠
    我的URL包含错误的双斜杠(“//”),我需要将其转换为单斜杠。不用说,我想保持“https:”后面的双斜杠不变。可以在字符串中进行此更改的最短Python代码是什么?我一直在尝试使用re.sub,带有冒号否定的正则表达式(即,[^:](//)),但它想要替换整个匹配项(包括前面......
  • 如何使用 Selenium Python 搜索 Excel 文件中的文本
    我有一些数据在Excel文件中。我想要转到Excel文件,然后搜索文本(取自网站表),然后获取该行的所有数据,这些数据将用于在浏览器中填充表格。示例:我希望selenium搜索ST0003然后获取名称,该学生ID的父亲姓名,以便我可以在大学网站中填写此信息。我想我会从网站......
  • Python 套接字请求在很多情况下都会失败
    我在python中尝试了超过5种不同的方法,尽管人们说它在其他论坛上有效,但所有这些方法都惨遭失败。importsocketmessage="test"clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)clientsocket.connect(('1.1.1.1',80))clientsocket.send(mes......
  • Python 网络套接字
    我一直尝试通过Python访问该网站的websocket,但是需要绕过CloudFlare,现在我尝试通过cookie进行绕过,但是这不起作用。我已经尝试在没有cookie的情况下执行此操作,但这也不起作用。importwebsocketimportbase64importosdriver=selenium.webdriver.Firefox()driver.ge......
  • 如何在Python中使用Selenium提取data-v-xxx?
    因为我想查看每个class='num'内的文本是否大于0。如果测试通过,那么我需要获取venuen-name内的文本。我观察到,data-v是相同的。所以我的方法是获取相同的data-v-<hashvalue>来查找场地名称。我尝试了不同的方法来提取,但仍然无法提取。有什么建议吗?这是DOM<div......
  • Python:添加异常上下文
    假设我想提出一个异常并提供额外的处理信息;最好的做法是什么?我想出了以下方法,但对我来说有点可疑:definternal_function():raiseValueError("smellysocks!")defcontext_function():try:internal_function()exceptExceptionase:......
  • 【视频】Python遗传算法GA优化SVR、ANFIS预测证券指数ISE数据-CSDN博客
    全文链接:https://tecdat.cn/?p=37060本文旨在通过应用多种机器学习技术,对交易所的历史数据进行深入分析和预测。我们帮助客户使用了遗传算法GA优化的支持向量回归(SVR)、自适应神经模糊推理系统(ANFIS)等方法,对数据进行了特征选择、数据预处理、模型训练与评估。实验结果表明,这些方法......
  • Python学习笔记42:游戏篇之外星人入侵(三)
    前言在之前我们已经创建好了目录,并且编写好了游戏入口的模块。今天的内容主要是讲讲需求的分析以及项目各模块的代码初步编写。在正式编写代码前,碎碎念几句。在正式编写一个项目代码之前,实际是有很多工作要做的。就项目而言,简单的定项,需求对齐,项目架构设计,实际的代码编写,......
  • Python入门知识点 5--流程控制语句
    先来分享一个pycharm使用小技巧   红色波浪线:提醒可能报错   黄色波浪线:提醒书写不规范,ctrl+alt+l去掉黄线   code--Reformatcode,就可以去掉黄线,调整代码格式1、程序三大执行流程(1)顺序执行        程序执行时,代码从上往下,从左往右执行,中间......