o
    biE                     @   s  d Z ddlZddlZddlmZ ddlmZ ddlmZ zddl	Z	W n+ e
yM   zddlZ	W n e
yJ   zddlZ	W n e
yG   dZ	Y nw Y nw Y nw dd Zdd	 Zd
d Zdd Zdd Zdd Zed									dddZed									dddZdS )z)Utilities related to model visualization.    N)tree)keras_export)io_utilsc                   C   s   t duS )z#Returns True if PyDot is available.N)pydot r   r   W/home/ubuntu/.local/lib/python3.10/site-packages/keras/src/utils/model_visualization.pycheck_pydot   s   r   c                	   C   s<   t  sdS ztjt  W dS  ttjfy   Y dS w )z6Returns True if both PyDot and Graphviz are available.FT)r   r   DotcreateOSErrorPydotExceptionr   r   r   r   check_graphviz   s   r   c                 C   sN   t t|}t t|}| ||s%t||}|dd | | d S d S )Npenwidth2)stridget_edger   Edgesetadd_edge)dotsrcdstsrc_iddst_idedger   r   r   r   *   s   r   c                 C   s>   t | jdr| jj}|S t | jdr| jj}|S t| j}|S )Nname__name__)hasattr
activationr   r   r   )layeractivation_namer   r   r   get_layer_activation_name3   s   
r"   c              	   K   s*  | j j}|d}|d}|d}|d}|d}|r&td| d}tdd	 ||fD }	|r9|	d
7 }	td|	}
|rP|d|
 d| j d| d7 }n|d|
 d| d7 }|rtt| drt| jd urt|d|
 dt	|  d7 }g }|rd }d }zt
dd | j}t
dd | j}W n ttfy   Y nw dd }|dkr|d|| d |d|| d |rd }zt
dd | j}W n ttfy   Y nw |d|pd d |rt| d r| jr| jr|d! n|d" |rt|}
nd}
|r|d#d$| d%7 }|d&7 }|S )'Nshow_layer_namesshow_layer_activations
show_dtypeshow_shapesshow_trainablezInvalid kwargs: zC<<table border="0" cellborder="1" bgcolor="black" cellpadding="10">c                 s   s    | ]}t |V  qd S N)int).0xr   r   r   	<genexpr>L   s    z#make_layer_label.<locals>.<genexpr>      z<tr><td colspan="z9" bgcolor="black"><font point-size="16" color="white"><b>z</b> (z)</font></td></tr>z</b></font></td></tr>r   z!<tr><td bgcolor="white" colspan="z'"><font point-size="14">Activation: <b>c                 S      | j S r(   shaper+   r   r   r   <lambda>p       z"make_layer_label.<locals>.<lambda>c                 S   r/   r(   r0   r2   r   r   r   r3   q   r4   c                 S   sR   | d ur%t | trddd |  D }n|  }|dddd}|S d}|S )Nz, c                 S   s   g | ]\}}| d | qS )z: r   )r*   kvr   r   r   
<listcomp>y   s    z:make_layer_label.<locals>.format_shape.<locals>.<listcomp>} {?)
isinstancedictjoinitemsreplace)r1   	shape_strr   r   r   format_shapeu   s   
z&make_layer_label.<locals>.format_shape
InputLayerz:<td bgcolor="white"><font point-size="14">Input shape: <b>z</b></font></td>z;<td bgcolor="white"><font point-size="14">Output shape: <b>c                 S   r/   r(   )dtyper2   r   r   r   r3      r4   z;<td bgcolor="white"><font point-size="14">Output dtype: <b>r;   	trainablezZ<td bgcolor="forestgreen"><font point-size="14" color="white"><b>Trainable</b></font></td>z\<td bgcolor="firebrick"><font point-size="14" color="white"><b>Non-trainable</b></font></td>z<tr>r9   z</tr>z	</table>>)	__class__r   pop
ValueErrorsummaxr   r   r   r"   r   map_structureinputoutputAttributeErrorappendweightsrE   lenr>   )r    kwargs
class_namer#   r$   r%   r&   r'   tablecolspan_maxcolspancolsinput_shapeoutput_shaperB   rD   r   r   r   make_layer_label=   s   







rZ   c                 K   sJ   t jtt| t| fi |d}|dd |dd |dd |S )N)labelfontname	Helveticaborder0margin)r   Noder   r   rZ   r   )r    rR   noder   r   r   	make_node   s
   "rc   zkeras.utils.model_to_dotFTTB   c
                 K   s$  ddl m} | jstdddlm} ddlm} t s td|r8t	j
d| jd}|d	| j |d
d n"t	 }|d| |dd |d| |dd |jdd |
dddurftd|
rotd|
 |||||	d}
t| |jr| j}nt| |jst| fi |
}|| |S | j}t|D ]/\}}|rt||j|jfrt||||||d||	d	}|| qt|fi |
}|| qt| |jr|stt|d D ]}t||| ||d   q|S | jdd }|D ]}t|jD ]\}}t| |jr|||| jvrqt|jD ]u\}}|j }|j!du r'q|j!j|j" }|j#}|j!}|}|sAt||| qt||j|jfr^|j$| j \}}}t||j|jfsKt||j|jfrt||jrw|j%| j j!}n|jd }t||j|jfsht||| qqq|S )a  Convert a Keras model to dot format.

    Args:
        model: A Keras model instance.
        show_shapes: whether to display shape information.
        show_dtype: whether to display layer dtypes.
        show_layer_names: whether to display layer names.
        rankdir: `rankdir` argument passed to PyDot,
            a string specifying the format of the plot: `"TB"`
            creates a vertical plot; `"LR"` creates a horizontal plot.
        expand_nested: whether to expand nested Functional models
            into clusters.
        dpi: Image resolution in dots per inch.
        subgraph: whether to return a `pydot.Cluster` instance.
        show_layer_activations: Display layer activations (only for layers that
            have an `activation` property).
        show_trainable: whether to display if a layer is trainable.

    Returns:
        A `pydot.Dot` instance representing the Keras model or
        a `pydot.Cluster` instance representing nested model if
        `subgraph=True`.
    r   )make_node_keyyThis model has not yet been built. Build the model first by calling `build()` or by calling the model on a batch of data.)
functional)
sequentialzFYou must install pydot (`pip install pydot`) for model_to_dot to work.dashed)style
graph_namer[   	labeljustlrankdirconcentrateTdpisplinesorthorecordr0   layer_rangeN.Argument `layer_range` is no longer supported. Unrecognized keyword arguments: )r#   r$   r%   r&   r'   )subgraphr$   r'   r.   )&keras.src.ops.functionrf   builtrH   keras.src.modelsrh   ri   r   ImportErrorr   Clusterr   r   r	   set_node_defaultsrG   r<   
Sequentiallayers
Functionalrc   add_node_operations	enumeratemodel_to_dotadd_subgraphrangerQ   r   _inbound_nodes_nodesinput_tensors_keras_history	operation
node_indextensor_indexoutputsinputs)modelr&   r%   r#   ro   expand_nestedrq   rx   r$   r'   rR   rf   rh   ri   r   r   rb   ir    submodelinbound_indexinbound_nodeinput_indexinput_tensorinput_history
input_nodeoutput_indexsourcedestination_r   r   r   r      s   %







Lr   zkeras.utils.plot_model	model.pngc
                 K   s*  | j stdt sd}dtjv rt| dS t|t s1d}dtjv r-t| dS t||
	dddur=td|
rFtd|
 t
| ||||||||	d		}t|}|du r]dS tj|\}}|sjd
}n|dd }|j||d |dkrzddlm} |j|dW S  ty   Y dS w dS )a  Converts a Keras model to dot format and save to a file.

    Example:

    ```python
    inputs = ...
    outputs = ...
    model = keras.Model(inputs=inputs, outputs=outputs)

    dot_img_file = '/tmp/model_1.png'
    keras.utils.plot_model(model, to_file=dot_img_file, show_shapes=True)
    ```

    Args:
        model: A Keras model instance
        to_file: File name of the plot image.
        show_shapes: whether to display shape information.
        show_dtype: whether to display layer dtypes.
        show_layer_names: whether to display layer names.
        rankdir: `rankdir` argument passed to PyDot,
            a string specifying the format of the plot: `"TB"`
            creates a vertical plot; `"LR"` creates a horizontal plot.
        expand_nested: whether to expand nested Functional models
            into clusters.
        dpi: Image resolution in dots per inch.
        show_layer_activations: Display layer activations (only for layers that
            have an `activation` property).
        show_trainable: whether to display if a layer is trainable.

    Returns:
        A Jupyter notebook Image object if Jupyter is installed.
        This enables in-line display of the model plots in notebooks.
    rg   zFYou must install pydot (`pip install pydot`) for `plot_model` to work.zIPython.core.magics.namespaceNznYou must install graphviz (see instructions at https://graphviz.gitlab.io/download/) for `plot_model` to work.ru   rv   rw   )r&   r%   r#   ro   r   rq   r$   r'   pngr.   )formatpdfr   )display)filename)rz   rH   r   sysmodulesr   	print_msgr|   r   rG   r   r   ospathsplitextwriteIPythonr   Image)r   to_filer&   r%   r#   ro   r   rq   r$   r'   rR   messager   r   	extensionr   r   r   r   
plot_model  sb   0



r   )	FFTrd   Fre   FFF)	r   FFFrd   Fre   FF)__doc__r   r   	keras.srcr   keras.src.api_exportr   keras.src.utilsr   r   r|   pydot_ng	pydotplusr   r   r   r"   rZ   rc   r   r   r   r   r   r   <module>   sd    	
} S