8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

将转换后的 tensorflowjs 模型导入 React 时,使用 'loadLayersModel' 时出现错误

booyaakaashaa 2月前

40 0

我是 ML 和 tf 的新手。这是我第一次尝试用它做一个项目。我在 tensorflow 中训练了一个 siamese 模型,并将其保存为 .h5 格式。然后,我使用了 \'tensorflowjs_converter&...

我是 ML 和 tf 的新手。这是我第一次尝试用它做一个项目。我在 tensorflow 中训练了一个 siamese 模型,并将其保存为 .h5 格式。然后,我使用 \'tensorflowjs_converter\' 将其转换为 javascript 可读格式,如下所示: 在此处输入图像描述

group1-shardxxof38 是 BIN 文件,model 是 json 文件。然后,我尝试使用以下代码将模型加载到我的 React 应用程序中:

const tf = require('@tensorflow/tfjs-node');
const fs = require('fs');

// Define and register your custom layer
class L1Dist extends tf.layers.Layer {
    constructor(config) {
        super(config);
        this.supportsMasking = true;
    }

    call(inputs) {
        return tf.tidy(() => {
            if (!Array.isArray(inputs) || inputs.length !== 2) {
                throw new Error(`Expected inputs to be an array of two elements, but got: ${JSON.stringify(inputs)}`);
            }

            let inputEmbedding, validationEmbedding;

            try {
                inputEmbedding = inputs[0] instanceof tf.Tensor ? inputs[0] : tf.tensor(inputs[0]);
                validationEmbedding = inputs[1] instanceof tf.Tensor ? inputs[1] : tf.tensor(inputs[1]);
            } catch (error) {
                console.error('Error creating tensors:', error);
                console.error('Input shapes:', 
                    inputs[0] instanceof tf.Tensor ? inputs[0].shape : 'Not a tensor',
                    inputs[1] instanceof tf.Tensor ? inputs[1].shape : 'Not a tensor'
                );
                throw error;
            }

            if (!inputEmbedding.shape.every((dim, i) => dim === validationEmbedding.shape[i])) {
                throw new Error(`Input shapes do not match: ${inputEmbedding.shape} vs ${validationEmbedding.shape}`);
            }

            return tf.abs(tf.sub(inputEmbedding, validationEmbedding));
        });
    }

    computeOutputShape(inputShape) {
        return inputShape[0];
    }

    static get className() {
        return 'L1Dist';
    }
}

tf.serialization.registerClass(L1Dist);

async function loadModel(modelPath) {
    try {
        // First, try loading the model normally
        const model = await tf.loadLayersModel(`file://${modelPath}`);
        console.log('Model loaded successfully');
        return model;
    } catch (error) {
        console.log('Error loading model:', error.message);
        console.log('Attempting to load and fix model configuration...');

        // Load the model JSON file
        const modelJSON = JSON.parse(fs.readFileSync(modelPath, 'utf8'));

        // Function to fix inboundNodes
        function fixInboundNodes(obj) {
            if (Array.isArray(obj)) {
                return obj.map(fixInboundNodes);
            } else if (typeof obj === 'object' && obj !== null) {
                const newObj = {};
                for (const [key, value] of Object.entries(obj)) {
                    if (key === 'inboundNodes') {
                        newObj[key] = value.map(node => {
                            if (Array.isArray(node)) {
                                return node;
                            } else if (typeof node === 'object') {
                                return [node.args, node.kwargs];
                            } else {
                                return [node];
                            }
                        });
                    } else {
                        newObj[key] = fixInboundNodes(value);
                    }
                }
                return newObj;
            }
            return obj;
        }

        // Fix the entire model topology
        modelJSON.modelTopology = fixInboundNodes(modelJSON.modelTopology);

        console.log('Modified model configuration:');
        console.log(JSON.stringify(modelJSON.modelTopology, null, 2));

        // Load the model with the modified configuration
        try {
            const model = await tf.loadLayersModel(tf.io.fromMemory(modelJSON));
            console.log('Model loaded successfully with modified configuration');
            return model;
        } catch (loadError) {
            console.error('Error loading modified model:', loadError);
            throw loadError;
        }
    }
}

async function loadAndTestModel() {
    const modelPath = 'C://Program_mine/Facial_recognition/facial-recognition-app/facial-recognition-backend/src/models/web_model/model.json';

    try {
        const siameseModel = await loadModel(modelPath);

        // Test the model
        const testInput1 = tf.randomNormal([1, 105, 105, 3]);
        const testInput2 = tf.randomNormal([1, 105, 105, 3]);
        const prediction = siameseModel.predict([testInput1, testInput2]);
        console.log('Test prediction shape:', prediction.shape);
        prediction.print();

        tf.dispose([testInput1, testInput2, prediction]);

        return siameseModel;

    } catch (error) {
        console.error('Error during model loading or analysis:', error);
        if (error.stack) {
            console.error('Stack trace:', error.stack);
        }
        throw error;
    }
}

module.exports = { loadAndTestModel };

函数 fixInboundNodes() 尝试将 model.json 文件中的对象转换为数组。但是,仍然显示错误消息: 加载修改后的模型时出错:ValueError:配置已损坏,nodeData 应为数组:[object Object]。 我已检查 model.json 的路径和使用函数 \'tensorflowjs_converter\' 的文档。

正如您在上面的代码中看到的,我已经通过 jupyterlab 在 wsl2 环境中训练了我的模型,并且我也在 wsl2 中进行了转换。然后,我将转换后的文件 web_model 到 windows 环境中。我不知道这是否相关。此外,我尝试通过在 js 中构建相同的模型直接分配权重。然而,加载的权重不正确。因此,将我的模型从 tensorflow 加载到 tensorjs 的问题仍然存在。:(

帖子版权声明 1、本帖标题:将转换后的 tensorflowjs 模型导入 React 时,使用 'loadLayersModel' 时出现错误
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由booyaakaashaa在本站《tensorflow》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 我正在学习由 Aladdin Persson 编写的关于数据增强的教程。在该教程中,TensorFlow 中的一些预处理模块当时(3 年前)仍在进行实验,例如 RandomFlip、

    我正在学习由 aladdin persson 编写的关于数据增强的教程。在教程中,TensorFlow 中的一些预处理模块当时(3 年前)仍在进行实验,例如 RandomFlip、Resizing。因此教程使用了类似 layer.experimental.preprocessing.Resizing(\'data property\') 的代码。然而,尽管 3 年前教程中的代码输出没有引发任何错误,但现在我却没有得到无错误的输出,这些是我一直收到的带有回溯的错误:

    Traceback (most recent call last):
      File "c:\Users\USER\CODE\PycharmProjects\pythonProject2Conda\main4.py", line 54, in <module>
        layers.experimental.preprocessing.Resizing(height=32, width=32),
        ^^^^^^^^^^^^^^^^^^^
    AttributeError: module 'keras._tf_keras.keras.layers' has no attribute 'experimental'
    

    这是实际的代码主体,根据我的理解,它应该用于训练我的神经网络进行数据增强。

    import os
    os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
    import tensorflow as tf
    from tensorflow import keras
    from tensorflow.keras import layers, regularizers
    import tensorflow_datasets as tfds
    import pandas as pd
    from tensorflow.keras.optimizers.legacy import Adam
    
    #HYPER PARAMETERS
    
    (ds_train, ds_test), ds_info = tfds.load(
        "cifar10",
        split=["train", "test"],
        shuffle_files=True,
        as_supervised=True,
        with_info=True
    )
    
    def normalize_img(image, label):
        return tf.cast(image, tf.float32)/255.0, label
    
    AUTOTUNE = tf.data.experimental.AUTOTUNE
    BATCH_SIZE = 32
    
    def augment(image, label):
        new_height = new_width = 32
        image = tf.image.resize(image, (new_height, new_width))
    
        if tf.random.uniform((), minval=0, maxval=1) <0.1:
            image = tf.tile(tf.image.rgb_to_grayscale(image), [1,1,3])
        
        image = tf.image.random_brightness(image, max_delta = 0.1)
        image = tf.image.random_contrast(image, lower=0.1, upper=0.2)
    
        image = tf.image.random_flip_left_right(image) #50% of cases will be flipped left and right
        # image = tf.image.random_flip_up_down(image) 50%
    
        return image, label
    
    ds_train = ds_train.map(normalize_img, num_parallel_calls=AUTOTUNE)
    ds_train = ds_train.cache()
    ds_train = ds_train.shuffle(ds_info.splits["train"].num_examples)
    #ds_train = ds_train.map(augment, num_parallel_calls=AUTOTUNE)
    ds_train = ds_train.batch(BATCH_SIZE)
    ds_train = ds_train.prefetch(AUTOTUNE)
    
    ds_test = ds_test.map(normalize_img, num_parallel_calls=AUTOTUNE)
    de_test = ds_test.batch(BATCH_SIZE)
    ds_test = ds_test.prefetch(AUTOTUNE)
    
    
    data_augmentation = keras.Sequential([
        layers.experimental.preprocessing.Resizing(height=32, width=32),
        layers.experimental.preprocessing.RandomFlip(mode="horizontal"),
        layers.experimental.preprocessing.RandomContrast(factor=0.1),
    ])
    model = keras.Sequential ([
        keras.Input((32, 32, 3)),
        
        layers.Conv2D(4, 3, padding="same", activation='relu'),
        layers.Conv2D(8, 3, padding="same", ctivation='relu'),
        layers.MaxPooling2D(),
        layers.Conv2D(16, 3, activation='relu'),
        layers.Flatten(),
        layers.Dense(64, activation="relu"),
        layers.Dense(10),
    
    ])
    
    model.compile(
        optimizer=keras.optimizers.Adam(3e-4),
        loss = keras.losses.SparseCategoricalCrossentropy(from_logits=True),
        metrics=["accuracy"],
    
    )
    
    model.fit(ds_train, epochs=5, verbose=2)
    model.evaluate(ds_test)
    
    
    
  • phd 2月前 0 只看Ta
    引用 3

    三年前的“实验性”功能现在不再是实验性的,这应该并不奇怪!毕竟,将新功能移出该阶段才是目标。

    RandomFlip , Resizing RandomContrast 现已成为成熟的功能,并且已从其语法中删除 \'.experimental.preprocessing\' 以反映这一点。

    用这个 data_augmentation 替换你的

    data_augmentation = keras.Sequential([
        layers.Resizing(height=32, width=32),
        layers.RandomFlip(mode="horizontal"),
        layers.RandomContrast(factor=0.1),
    ])
    
  • 我正在尝试过滤掉一个键,在本例中是从嵌套的对象数组中计数的。我有 let test = [ { \'id\':\'c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8\', \'

    在本例中,我试图 count 从嵌套的对象数组中过滤出一个键。

    我有

    let test  = [
     {
      "id": "c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8",
      "label": "Sector2",
      "options": {
       "62f92fab79ac81d933765bd0bbc4a1f5ea26cb3a088bcb4e6e": {
        "index": 0,
        "value": "Bob",
        "label": "Bob",
        "count": 1
       },
       "2fe91aa3567c0d04c521dcd2fc7e40d7622bb8c3f594d503da": {
        "index": 1,
        "value": "Student",
        "label": "Student",
        "count": 1
       },
       "c59ea1159f33b91a7f6edc6925be5e373fc543e4": {
        "index": 2,
        "value": "BBB",
        "label": "BBB",
        "count": 1
       },
       "c59ea1159f33b91a7f6edc6925be5e373fc54AAA": {
        "index": 3,
        "value": "Orange Duck",
        "label": "Orange Duck",
        "count": 1
       }
      }
     },
     {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e951709485",
      "label": "Brown Cow"
     },
     {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e95170ZZZ",
      "label": "Red Fish"
     }
    ]
    
     test = test.filter(item => item[0].options['count']);
    

    但我得到了 Cannot read properties of undefined

    我正在尝试从所有具有选项的测试元素中过滤掉计数

    期望输出是

    谢谢

    [
     {
      "id": "c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8",
      "label": "Sector2",
      "options": {
       "62f92fab79ac81d933765bd0bbc4a1f5ea26cb3a088bcb4e6e": {
        "index": 0,
        "value": "Bob",
        "label": "Bob"
       },
       "2fe91aa3567c0d04c521dcd2fc7e40d7622bb8c3f594d503da": {
        "index": 1,
        "value": "Student",
        "label": "Student"
       },
       "c59ea1159f33b91a7f6edc6925be5e373fc543e4": {
        "index": 2,
        "value": "BBB",
        "label": "BBB",
        "count": 1
       },
       "c59ea1159f33b91a7f6edc6925be5e373fc54AAA": {
        "index": 3,
        "value": "Orange Duck",
        "label": "Orange Duck"
       }
      }
     },
     {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e951709485",
      "label": "Brown Cow"
     },
     {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e95170ZZZ",
      "label": "Red Fish"
     }
    ]
    
  • const users = { user1: 18273, user2: 92833, user3: 90315 }//答案const usersArray = Object.entries(users).map((keys, value)=> {return keys[0] + ' ' + value[1]});console.log(usersArray);//...

    const users = { user1: 18273, user2: 92833, user3: 90315 }
    

    //回答

    const usersArray = Object.entries(users).map((keys, value)=> {return keys[0] + ' ' + value[1]});
    console.log(usersArray);
    

    //输出:

     ['user1 undefined', 'user2 undefined', 'user3 undefined']
    

    我希望它是这样的:

     [ [ 'user1', 18273 ], [ 'user2', 92833 ], [ 'user3', 90315 ] ]
    
  • 过滤() 用于 filter 数组的一部分,而不是删除对象的嵌套键。


    实现期望结果的最简单方法是:

    1. 循环遍历每个对象
    2. 如果此对象有 options
    3. 循环遍历每一个 options
    4. 使用 delete 删除 count 当前对象的

    const data = [{"id": "c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8", "label": "Sector2", "options": {"62f92fab79ac81d933765bd0bbc4a1f5ea26cb3a088bcb4e6e": {"index": 0, "value": "Bob", "label": "Bob", "count": 1 }, "2fe91aa3567c0d04c521dcd2fc7e40d7622bb8c3f594d503da": {"index": 1, "value": "Student", "label": "Student", "count": 1 }, "c59ea1159f33b91a7f6edc6925be5e373fc543e4": {"index": 2, "value": "BBB", "label": "BBB", "count": 1 }, "c59ea1159f33b91a7f6edc6925be5e373fc54AAA": {"index": 3, "value": "Orange Duck", "label": "Orange Duck", "count": 1 } } }, {"id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e951709485", "label": "Brown Cow" }, {"id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e95170ZZZ", "label": "Red Fish" } ];
    
    for (let i in data) {
        if (data[i]?.options) {
            for (let j in data[i].options) {
                delete data[i].options[j]?.count;
            }
        }
    }
    
    console.log(data);
  • 您可以解构对象并删除不需要的属性。

    const
        filter = ({ count, ...o }) => Object.fromEntries(Object
            .entries(o)
            .map(([k, v]) => [k, v && typeof v === 'object' ? filter(v) : v])
        ),
        data = [{ id: "c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8", label: "Sector2", options: { "62f92fab79ac81d933765bd0bbc4a1f5ea26cb3a088bcb4e6e": { index: 0, value: "Bob", label: "Bob", count: 1 }, "2fe91aa3567c0d04c521dcd2fc7e40d7622bb8c3f594d503da": { index: 1, value: "Student", label: "Student", count: 1 }, c59ea1159f33b91a7f6edc6925be5e373fc543e4: { index: 2, value: "BBB", label: "BBB", count: 1 }, c59ea1159f33b91a7f6edc6925be5e373fc54AAA: { index: 3, value: "Orange Duck", label: "Orange Duck", count: 1 } } }, { id: "f794c6a52e793ee6f5c42cd5df6b4435236e3495e951709485", label: "Brown Cow" }, { id: "f794c6a52e793ee6f5c42cd5df6b4435236e3495e95170ZZZ", label: "Red Fish" }],
        result = data.map(filter);
    
     console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
  • let test  = [
     {
      "id": "c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8",
      "label": "Sector2",
      "options": {
       "62f92fab79ac81d933765bd0bbc4a1f5ea26cb3a088bcb4e6e": {
        "index": 0,
        "value": "Bob",
        "label": "Bob",
        "count": 1
       },
       "2fe91aa3567c0d04c521dcd2fc7e40d7622bb8c3f594d503da": {
        "index": 1,
        "value": "Student",
        "label": "Student",
        "count": 1
       },
       "c59ea1159f33b91a7f6edc6925be5e373fc543e4": {
        "index": 2,
        "value": "BBB",
        "label": "BBB",
        "count": 1
       },
       "c59ea1159f33b91a7f6edc6925be5e373fc54AAA": {
        "index": 3,
        "value": "Orange Duck",
        "label": "Orange Duck",
        "count": 1
       }
      }
     },
     {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e951709485",
      "label": "Brown Cow"
     },
     {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e95170ZZZ",
      "label": "Red Fish"
     }
    ]
    
    
    
    test = test.map(o => !o.options ? o : Object.fromEntries(
      Object.entries(o.options).map(([key, {
        count,
        ...rest
      }]) => [
        key, rest
      ])
    ));
    
    console.log(test)
  • 对 OP 问题的 通用解决方案 无论提供的数据结构如何 ,都会在结构上 克隆 这样的对象 与提供的要 省略的键/属性名称 匹配的 任何 属性 ...

    let sampleData = [{
      "id": "c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8",
      "label": "Sector2",
      "options": {
        "62f92fab79ac81d933765bd0bbc4a1f5ea26cb3a088bcb4e6e": {
          "index": 0,
          "value": "Bob",
          "label": "Bob",
          "count": 1
        },
        "2fe91aa3567c0d04c521dcd2fc7e40d7622bb8c3f594d503da": {
          "index": 1,
          "value": "Student",
          "label": "Student",
          "count": 1
        },
        "c59ea1159f33b91a7f6edc6925be5e373fc543e4": {
          "index": 2,
          "value": "BBB",
          "label": "BBB",
          "count": 1
        },
        "c59ea1159f33b91a7f6edc6925be5e373fc54AAA": {
          "index": 3,
          "value": "Orange Duck",
          "label": "Orange Duck",
          "count": 1
        }
      }
    }, {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e951709485",
      "label": "Brown Cow"
    }, {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e95170ZZZ",
      "label": "Red Fish"
    }];
    
    console.log(
      cloneDataAndIgnoreKeys(
        sampleData,
        new Set(['count']),
      )
    );
    .as-console-wrapper { min-height: 100%!important; top: 0; }
    <script>
    function cloneDataAndIgnoreKeys(
      dataSource, ignoredKeys = new Set, dataTarget = {}
    ) {
      if (Array.isArray(dataSource)) {
    
        dataTarget = dataSource
          .map(item =>
            cloneDataAndIgnoreKeys(item, ignoredKeys)
          );
      } else if (!!dataSource && (typeof dataSource === 'object')) {
    
        dataTarget = Object
          .entries(dataSource)
          .reduce((target, [key, value]) => {
    
            if (!ignoredKeys.has(key)) {
              target[key] =
                cloneDataAndIgnoreKeys(value, ignoredKeys);
            }
            return target;
    
          }, dataTarget);
    
      } else {
        dataTarget = dataSource;
      }
      return dataTarget;
    }
    </script>
  • 您可以像这样用一行代码来完成它:

    const data = [{"id": "c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8", "label": "Sector2", "options": {"62f92fab79ac81d933765bd0bbc4a1f5ea26cb3a088bcb4e6e": {"index": 0, "value": "Bob", "label": "Bob", "count": 1 }, "2fe91aa3567c0d04c521dcd2fc7e40d7622bb8c3f594d503da": {"index": 1, "value": "Student", "label": "Student", "count": 1 }, "c59ea1159f33b91a7f6edc6925be5e373fc543e4": {"index": 2, "value": "BBB", "label": "BBB", "count": 1 }, "c59ea1159f33b91a7f6edc6925be5e373fc54AAA": {"index": 3, "value": "Orange Duck", "label": "Orange Duck", "count": 1 } } }, {"id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e951709485", "label": "Brown Cow" }, {"id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e95170ZZZ", "label": "Red Fish" } ];
    
    data.forEach(i => Object.values(i.options ?? {}).forEach(i => delete i.count))
    
    console.log(data);
  • 引用 11

    我同意上面的例子,现在来解释一下。

    未定义原因:

    map 函数在回调函数中需要两个参数:keys(键值对数组)和 value(原始数组中当前元素的索引)。在您的代码中,您使用 value 好像它包含用户 ID,但它实际上指的是 keys 数组的第二个索引,该索引始终未定义。

    为了修复这个问题,请从键数组的索引 1 访问用户 ID:

    const usersArray = Object.entries(users).map(keys => keys[0] + ' ' + keys[1]);
    

    现在输出格式为:

    [ [ 'user1, 18273' ], [ 'user2, 92833' ], [ 'user3, 90315' ] ]
    

    您只需将返回设置为[]:

    const usersArray = Object.entries(users).map(keys => [keys[0] + ' ' + keys[1]]);
    
    • 使用 map 函数来迭代你的数组。
    • 生成您的选项的副本。
    • 利用 for-in 循环检查对象属性并将其从数组中删除。
    • 将此代码合并到您的项目中时,请确保包含以下调整以避免类型错误。它的在线编译器不接受任何类型。

    删除(选项为任意).count;

    (newItem.options 作为任何)?.optionKey;

    谢谢

    let test  = [
     {
      "id": "c3c6f410f58e5836431b473ebcf134756232d04f2bf35edff8",
      "label": "Sector2",
      "options": {
       "62f92fab79ac81d933765bd0bbc4a1f5ea26cb3a088bcb4e6e": {
        "index": 0,
        "value": "Bob",
        "label": "Bob",
        "count": 1
       },
       "2fe91aa3567c0d04c521dcd2fc7e40d7622bb8c3f594d503da": {
        "index": 1,
        "value": "Student",
        "label": "Student",
        "count": 1
       },
       "c59ea1159f33b91a7f6edc6925be5e373fc543e4": {
        "index": 2,
        "value": "BBB",
        "label": "BBB",
        "count": 1
       },
       "c59ea1159f33b91a7f6edc6925be5e373fc54AAA": {
        "index": 3,
        "value": "Orange Duck",
        "label": "Orange Duck",
        "count": 1
       }
      }
     },
     {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e951709485",
      "label": "Brown Cow"
     },
     {
      "id": "f794c6a52e793ee6f5c42cd5df6b4435236e3495e95170ZZZ",
      "label": "Red Fish"
     }
    ];
    
    let filteredTest = test.map(item => {
        if (item?.options) {
    
            const newItem = { ...item };
    
        for (const optionKey in newItem.options) 
      {
    
       if (newItem.options.hasOwnProperty(optionKey)) 
      {
    
      const option = newItem.options[optionKey];
       if (option && 'count' in option) {
            delete option?.count;
           }
         }
       }
    
    return newItem;
    
       }
    
     return item;
    
    });
    console.log(filteredTest);
返回
作者最近主题: