简体   繁体   English

ValueError:添加Keras层时格式错误的节点或带有ast.literal_eval()的字符串

[英]ValueError: malformed node or string with ast.literal_eval() when adding a Keras layer

I want to build a Keras Model evaluating strings. 我想建立一个评估字符串的Keras模型。 If I do the following: 如果我执行以下操作:

from keras.models import Sequential
from keras.layers import Dense

model = Sequential()
model.add(Dense(units=10, input_shape=(10,), activation='softmax'))

It works fine. 它工作正常。 And I can see the model.summary() . 我可以看到model.summary()

But, when I add the layer with ast.literal_eval() 但是,当我用ast.literal_eval()添加图层时

from keras.models import Sequential
from keras.layers import Dense
import ast

model = Sequential()
code = "model.add( Dense( input_shape=(10,), units=10, activation='softmax' ) )"
ast.literal_eval(code)

It throws me the next ValueError : 它抛出了下一个ValueError

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.5/ast.py", line 84, in literal_eval
    return _convert(node_or_string)
  File "/usr/lib/python3.5/ast.py", line 83, in _convert
    raise ValueError('malformed node or string: ' + repr(node))
ValueError: malformed node or string: <_ast.Call object at 0x7efc40c90e10>

If I use eval instead of ast.literal_eval it works too. 如果我使用eval而不是ast.literal_eval它也可以。

I'm using python3.5. 我正在使用python3.5。

A big mistake: literal_eval only works for literals . 一个大错误: literal_eval仅适用于文字 In this case, I have a Call . 在这种情况下,我有一个电话

The function literal_eval first parse the string. 函数literal_eval首先解析字符串。

From /usr/lib/python3.5/ast.py: lines 38-46 来自/usr/lib/python3.5/ast.py:行38-46

def literal_eval(node_or_string):
    """
    Safely evaluate an expression node or a string containing a Python
    expression.  The string or node provided may only consist of the following
    Python literal structures: strings, bytes, numbers, tuples, lists, dicts,
    sets, booleans, and None.
    """
    if isinstance(node_or_string, str):
        node_or_string = parse(node_or_string, mode='eval')

At this point, node_or_string is an instance of Expression . 此时, node_or_stringExpression的实例。 Then, literal_eval get the body. 然后, literal_eval获取正文。

From /usr/lib/python3.5/ast.py: lines 47-48 来自/usr/lib/python3.5/ast.py:行47-48

    if isinstance(node_or_string, Expression):
        node_or_string = node_or_string.body

And finally, literal_eval checks the type of the body ( node_or_string ). 最后, literal_eval检查正文的类型( node_or_string )。

From /usr/lib/python3.5/ast.py: lines 49-84 来自/usr/lib/python3.5/ast.py:行49-84

    def _convert(node):
        if isinstance(node, (Str, Bytes)):
            return node.s
        elif isinstance(node, Num):
            return node.n
        elif isinstance(node, Tuple):
            return tuple(map(_convert, node.elts))
        elif isinstance(node, List):
            return list(map(_convert, node.elts))
        elif isinstance(node, Set):
            return set(map(_convert, node.elts))
        elif isinstance(node, Dict):
            return dict((_convert(k), _convert(v)) for k, v
                        in zip(node.keys, node.values))
        elif isinstance(node, NameConstant):
            return node.value
        elif isinstance(node, UnaryOp) and \
             isinstance(node.op, (UAdd, USub)) and \
             isinstance(node.operand, (Num, UnaryOp, BinOp)):
            operand = _convert(node.operand)
            if isinstance(node.op, UAdd):
                return + operand
            else:
                return - operand
        elif isinstance(node, BinOp) and \
             isinstance(node.op, (Add, Sub)) and \
             isinstance(node.right, (Num, UnaryOp, BinOp)) and \
             isinstance(node.left, (Num, UnaryOp, BinOp)):
            left = _convert(node.left)
            right = _convert(node.right)
            if isinstance(node.op, Add):
                return left + right
            else:
                return left - right
        raise ValueError('malformed node or string: ' + repr(node))
    return _convert(node_or_string)

If the initial code was ast.literal_eval('1+1') (for example), now node_or_string would be an instance of BinOp . 如果初始代码是ast.literal_eval('1+1') (例如), node_or_string现在将是BinOp的实例。 But in the case of: 但在以下情况下:

code = "model.add( Dense( input_shape=(10,), units=10, activation='softmax' ) )"
ast.literal_eval(code)

The body will be an instance of Call , which does not appear among the valid types of the function. 正文将是Call一个实例,它不会出现在函数的有效类型中。

Eg: 例如:

import ast

code_nocall = "1+1"
node = ast.parse(code_nocall, mode='eval')
body = node.body
print(type(body)) # Returns <class '_ast.BinOp'>

code_call = "print('hello')"
node = ast.parse(code_call, mode='eval')
body = node.body
print(type(body)) # Returns <class '_ast.Call'>

Solution

The best solution I have found so far, to not use eval directly, is to perform the process manually. 到目前为止,我发现的最佳解决方案是不直接使用eval ,而是手动执行该过程。 With this function: 有了这个功能:

import ast

def eval_code(code):
    parsed = ast.parse(code, mode='eval')
    fixed = ast.fix_missing_locations(parsed)
    compiled = compile(fixed, '<string>', 'eval')
    eval(compiled)

Now it works: 它现在有效:

eval_code("print('hello world')")

from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
code = "model.add( Dense( input_shape=(10,), units=10, activation='softmax' ) )"
eval_code(code)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ast.literal_eval() ValueError: 格式错误的节点或字符串 - ast.literal_eval() ValueError: malformed node or string ValueError: 格式错误的节点或字符串 ast.literal_eval() - ValueError: malformed node or string with ast.literal_eval() ast.literal_eval ValueError(&#39;格式错误的字符串&#39;) - ast.literal_eval ValueError('malformed string') ValueError:使用ast.literal_eval时格式错误的字符串 - ValueError: malformed string when using ast.literal_eval 带有元组字符串表示的格式错误的字符串 ValueError ast.literal_eval() - Malformed String ValueError ast.literal_eval() with String representation of Tuple ValueError:使用ast.literal_eval的格式错误的字符串 - ValueError: malformed string using ast.literal_eval python:ast.literal_eval()提供ValueError:格式错误的字符串 - python: ast.literal_eval() gives ValueError: malformed string 当我使用 discord.py 使用 ast.literal_eval 时,第 1 行出现格式错误的节点或字符串 - malformed node or string on line 1 when I use ast.literal_eval using discord.py ast.literal_eval() 格式错误的节点或字符串,同时转换带有 array() 列表的字符串 - ast.literal_eval() malformed node or string while converting a string with list of array()s 使用ast.literal_eval时格式错误的字符串 - Malformed string while using ast.literal_eval
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM