networkx: remove edge with specific attribute from multigraph - networkx

I'd like to remove a specific edge (specific color) from a MultiGraph.
How can I do that?
Following code does not work.
#!/usr/bin/env python
import matplotlib.pyplot as plt
import networkx as nx
G = nx.MultiGraph()
# the_colored_graph.add_edge(v1, v2, "red")
G.add_edge(1, 2, color="red")
G.add_edge(2, 3, color="red")
G.add_edge(4, 2, color="green")
G.add_edge(2, 4, color="blue")
print (G.edges(data=True))
# G.remove_edge(2, 4, color="green")
#
selected_edge = [(u,v) for u,v,e in G.edges(data=True) if e['color'] == 'green']
print (selected_edge)
G.remove_edge(selected_edge[0][0], selected_edge[0][1])
print (G.edges(data=True))
nx.draw(G)
plt.show()

When constructing the multigraph, assign a "key" attribute to each edge (the key could be anything that disambiguates the parallel edges - say, the color):
G.add_edge(1, 2, color="red", key='red')
Remove an edges by specifying the end nodes and the key:
G.remove_edge(1, 2, key='red')

Related

TF Keras code adaptation from python2.7 to python3

I am working to adapt a python2.7 code that uses keras and tensorflow to implement a CNN but looks like the keras API has changed a little bit since when the original code was idealized. I keep getting an error about "Negative dimension after subtraction" and I can not find out what is causing it.
Unfortunately I am not able to provide an executable piece of code because I was not capable of make the original code works, but the repository containing all the source files can be found here.
The piece of code:
from keras.callbacks import EarlyStopping
from keras.layers.containers import Sequential
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Reshape, Flatten, Dropout, Dense
from keras.layers.embeddings import Embedding
from keras.models import Graph
from keras.preprocessing import sequence
filter_lengths = [3, 4, 5]
self.model = Graph()
'''Embedding Layer'''
self.model.add_input(name='input', input_shape=(max_len,), dtype=int)
self.model.add_node(Embedding(
max_features, emb_dim, input_length=max_len), name='sentence_embeddings', input='input')
'''Convolution Layer & Max Pooling Layer'''
for i in filter_lengths:
model_internal = Sequential()
model_internal.add(
Reshape(dims=(1, self.max_len, emb_dim), input_shape=(self.max_len, emb_dim))
)
model_internal.add(Convolution2D(
nb_filters, i, emb_dim, activation="relu"))
model_internal.add(
MaxPooling2D(pool_size=(self.max_len - i + 1, 1))
)
model_internal.add(Flatten())
self.model.add_node(model_internal, name='unit_' + str(i), input='sentence_embeddings')
What I have tried:
m = tf.keras.Sequential()
m.add(tf.keras.Input(shape=(max_len, ), name="input"))
m.add(tf.keras.layers.Embedding(max_features, emb_dim, input_length=max_len))
filter_lengths = [ 3, 4, 5 ]
for i in filter_lengths:
model_internal = tf.keras.Sequential(name=f'unit_{i}')
model_internal.add(
tf.keras.layers.Reshape(( 1, max_len, emb_dim ), input_shape=( max_len, emb_dim ))
)
model_internal.add(
tf.keras.layers.Convolution2D(100, i, emb_dim, activation="relu")
)
model_internal.add(
tf.keras.layers.MaxPooling2D(pool_size=( max_len - i + 1, 1 ))
)
model_internal.add(
tf.keras.layers.Flatten()
)
m.add(model_internal)
I do not expect a complete solution, what I am really trying to understand is what is the cause to the following error:
Negative dimension size caused by subtracting 3 from 1 for '{{node conv2d_5/Conv2D}} = Conv2D[T=DT_FLOAT, data_format="NHWC", dilations=[1, 1, 1, 1], explicit_paddings=[], padding="VALID", strides=[1, 200, 200, 1], use_cudnn_on_gpu=true](Placeholder, conv2d_5/Conv2D/ReadVariableOp)' with input shapes: [?,1,300,200], [3,3,200,100].

HoloViews/Panel - TypeError: unsupported operand type(s) for *: 'function' and 'Points'

I'm trying to create the parameter px on the holoviews.operation.datashader.spread operation interactively changeable together with an additional overlay.
The diagram with an IntSlider and the function returned by pn.bind(get_spreaded, px=px_slider) is working as expected when executing with pn.Column(px_slider, interactive)`.
But with an additional overlay, the line pn.Column(px_slider, interactive * other) reports TypeError: unsupported operand type(s) for *: 'function' and 'Points'.
How can I use the * operator with the function returned from pn.bind(...)?
Or is this the wrong way doing this? Is there a better and easier solution?
I ran the following code in jupyter lab:
import holoviews as hv
import panel as pn
import numpy as np
from holoviews.operation.datashader import rasterize, spread
import colorcet
import pandas as pd
hv.extension('bokeh')
pn.extension()
hv.opts.defaults(
hv.opts.Path(width=800, height=400),
hv.opts.Image(width=800, height=400)
)
def random_walk(n, f=200):
"""Random walk in a 2D space, smoothed with a filter of length f"""
xs = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f)/f).cumsum()
ys = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f)/f).cumsum()
xs += 0.1*np.sin(0.1*np.array(range(n-1+f))) # add wobble on x axis
xs += np.random.normal(0, 0.005, size=n-1+f) # add measurement noise
ys += np.random.normal(0, 0.005, size=n-1+f)
return np.column_stack([xs, ys])
# create a path and plot it
path = hv.Path([random_walk(10000, 30)])
path
# rasterize and show the plot
rasterized = rasterize(path).opts(colorbar=True, cmap=colorcet.fire, cnorm='log')
rasterized
# the callback for getting the spreaded plot
def get_spreaded(px=3, shape='circle'):
return spread(rasterized, px=px, shape=shape)
# show the plot returned from the callback
get_spreaded()
# create the slider for interactively changing the px value
px_slider = pn.widgets.IntSlider(name='Number of pixels to spread on all sides', start=0, end=10, value=3, step=1)
# bind the slider to the callback method
interactive = pn.bind(get_spreaded, px=px_slider)
# show only one plot without any overlay
pn.Column(px_slider, interactive)
# create data for an overlay
df = pd.DataFrame(data={'c1': [1, 2, 3, 4, 5], 'c2': [3, 4, 5, 6, 7]})
other = hv.Points(data=df)
other
# show both plots
pn.Column(px_slider, interactive * other)
The last line results in the following Error message:
#
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[159], line 1
----> 1 pn.Column(px_slider, interactive * other)
TypeError: unsupported operand type(s) for *: 'function' and 'Points'
I would expect, that there is some way to wrap the function and makes it possible to use the * operator. But I couldn't find a way yet.
Although in this particular case the return value of the function is something that HoloViews could (in principle) overlay with the other plot, HoloViews doesn't know that; the HoloViews * operator only knows how to handle HoloViews objects (Elements, HoloMaps, Layouts, and DynamicMaps), not bound Panel functions.
You could use a DynamicMap much like you used pn.bind, but here HoloViews operations already understand what to do with Panel widgets, so you can simply supply the widget to the spread operation (or any other operation's parameters):
import panel as pn, numpy as np, holoviews as hv, colorcet, pandas as pd
from holoviews.operation.datashader import rasterize, spread
hv.extension('bokeh')
pn.extension()
hv.opts.defaults(
hv.opts.Path(width=800, height=400),
hv.opts.Image(width=800, height=400)
)
def random_walk(n, f=200):
"""Random walk in a 2D space, smoothed with a filter of length f"""
xs = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f)/f).cumsum()
ys = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f)/f).cumsum()
xs += 0.1*np.sin(0.1*np.array(range(n-1+f))) # add wobble on x axis
xs += np.random.normal(0, 0.005, size=n-1+f) # add measurement noise
ys += np.random.normal(0, 0.005, size=n-1+f)
return np.column_stack([xs, ys])
# create plot with interactively controlled spreading
px_slider = pn.widgets.IntSlider(name='Number of pixels to spread on all sides',
start=0, end=10, value=3, step=1)
path = hv.Path([random_walk(10000, 30)])
rasterized = rasterize(path).opts(colorbar=True, cmap=colorcet.fire, cnorm='log')
spreaded= spread(rasterized, px=px_slider, shape='circle')
# create data for an overlay
df = pd.DataFrame(data={'c1': [1, 2, 3, 4, 5], 'c2': [3, 4, 5, 6, 7]})
other = hv.Points(data=df)
# show both plots
pn.Column(px_slider, spreaded * other)

ValueError: Cannot feed value of shape (1, 2048, 2048, 1) for Tensor 'image_tensor:0', which has shape '(?, ?, ?, 3)'

Using TensorFlow I am trying to detect one object(png and grayscale image). I have trained and exported a model.ckpt successfully. Now I am trying to restore the saved model.ckpt for prediction. Here is the script:
import numpy as np
import os
import six.moves.urllib as urllib
import sys
import tarfile
import tensorflow as tf
import zipfile
from collections import defaultdict
from io import StringIO
from matplotlib import pyplot as plt
from PIL import Image
if tf.__version__ != '1.4.0':
raise ImportError('Please upgrade your tensorflow installation to v1.4.0!')
# This is needed to display the images.
#matplotlib inline
# This is needed since the notebook is stored in the object_detection folder.
sys.path.append("..")
from utils import label_map_util
from utils import visualization_utils as vis_util
MODEL_NAME = 'melon_graph'
# Path to frozen detection graph. This is the actual model that is used for the object detection.
PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb'
# List of the strings that is used to add correct label for each box.
PATH_TO_LABELS = os.path.join('training', 'object_detection.pbtxt')
NUM_CLASSES = 1
detection_graph = tf.Graph()
with detection_graph.as_default():
od_graph_def = tf.GraphDef()
with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
serialized_graph = fid.read()
od_graph_def.ParseFromString(serialized_graph)
tf.import_graph_def(od_graph_def, name='')
label_map = label_map_util.load_labelmap(PATH_TO_LABELS)
categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True)
category_index = label_map_util.create_category_index(categories)
def load_image_into_numpy_array(image):
(im_width, im_height) = image.size
return np.array(image.getdata()).reshape((im_height, im_width, 1)).astype(np.float64)
# For the sake of simplicity we will use only 2 images:
# If you want to test the code with your images, just add path to the images to the TEST_IMAGE_PATHS.
PATH_TO_TEST_IMAGES_DIR = 'test_images'
TEST_IMAGE_PATHS = [ os.path.join(PATH_TO_TEST_IMAGES_DIR, 'te_data{}.png'.format(i)) for i in range(1, 336) ]
# Size, in inches, of the output images.
IMAGE_SIZE = (12, 8)
with detection_graph.as_default():
with tf.Session(graph=detection_graph) as sess:
# Definite input and output Tensors for detection_graph
image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
# Each box represents a part of the image where a particular object was detected.
detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
# Each score represent how level of confidence for each of the objects.
# Score is shown on the result image, together with the class label.
detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
num_detections = detection_graph.get_tensor_by_name('num_detections:0')
for image_path in TEST_IMAGE_PATHS:
image = Image.open(image_path)
# the array based representation of the image will be used later in order to prepare the
# result image with boxes and labels on it.
image_np = load_image_into_numpy_array(image)
# Expand dimensions since the model expects images to have shape: [1, None, None, 3]
image_np_expanded = np.expand_dims(image_np, axis=0)
# Actual detection.
(boxes, scores, classes, num) = sess.run([detection_boxes, detection_scores, detection_classes, num_detections], feed_dict={image_tensor: image_np_expanded})
# Visualization of the results of a detection.
vis_util.visualize_boxes_and_labels_on_image_array(image_np,np.squeeze(boxes),np.squeeze(classes).astype(np.float64), np.squeeze(scores), category_index, use_normalized_coordinates=True, line_thickness=5)
plt.figure(figsize=IMAGE_SIZE)
plt.imshow(image_np)
and this is the error
Traceback (most recent call last): File "cochlear_detection.py",
line 81, in
(boxes, scores, classes, num) = sess.run([detection_boxes, detection_scores, detection_classes, num_detections],
feed_dict={image_tensor: image_np_expanded}) File
"/anaconda/lib/python3.6/site-packages/tensorflow/python/client/session.py",
line 889, in run
run_metadata_ptr) File "/anaconda/lib/python3.6/site-packages/tensorflow/python/client/session.py",
line 1096, in _run
% (np_val.shape, subfeed_t.name, str(subfeed_t.get_shape()))) ValueError: Cannot feed value of shape (1, 2048, 2048, 1) for Tensor
'image_tensor:0', which has shape '(?, ?, ?, 3)'

Networkx - Get edge properties in Dijkstra path

I have the following graph
import networkx as nx
g = nx.MultiGraph()
#link 0
g.add_edge("A","B",cost=20,index=0)
#link 1
g.add_edge("A","C",cost=20,index=1)
#link 2
g.add_edge("B","C",cost=10,index=2)
#link 3
g.add_edge("B","D",cost=150,index=3)
#link 4
g.add_edge("C","D",cost=150,index=5)
g.add_edge("C","D",cost=200,index=6)
I'm trying to find the shortest path between A and D and that works
path=nx.dijkstra_path(g,"A","D",weight='cost')
->['A', 'C', 'D']
What i need is to get the edges info ( more specific the index) in this path.
Tryied to far :
edgesinpath=zip(path[0:],path[1:])
for (u,v ) in edgesinpath:
print u,v,g[u][v]
but of course this will out all the edges , that math the u,v in the path:
A C {0: {'index': 1, 'cost': 20}}
C D {0: {'index': 5, 'cost': 150}, 1: {'index': 6, 'cost': 200}}
Any idea how to get the correct information ? Is this available via networkx?
Thx.
One possible solution:
edges_ids = []
for u,v in edgesinpath:
edge = sorted(g[u][v], key=lambda x:g[u][v][x]['cost'])[0]
edges_ids.append(g[u][v][edge]['index'])
This choses for each multi-edge, the edge in your shortest path with a minimal cost.

NetworkXError: Node 8 has no position

I just started programming and recently I'm working in ipython notebook with networkx. This code below is working perfectly if you run it, but if you uncomment #G.add_edge(2, 8, egdes=6) it gives you the error NetworkXError: Node 8 has no position. Why does it only work until the sixth node?
import networkx as nx
import matplotlib.pyplot as plt
import pylab
%matplotlib inline
pos=nx.spring_layout(G)
G = nx.Graph()
G.add_edge(1, 2, egdes=1)
G.add_edge(1, 3, egdes=2)
G.add_edge(1, 4, egdes=3)
G.add_edge(1, 5, egdes=4)
G.add_edge(1, 6, egdes=5)
#G.add_edge(2, 8, egdes=6)
nx.draw(G,pos)
edge_labels=dict([((fe,se,),e['egdes'])
for fe,se,e in G.edges(data=True)])
nx.draw_networkx_edge_labels(G,pos,edge_labels)
pylab.show()
I hope one of you guys can help me, thanks in advance!
You need to create the node positions
pos=nx.spring_layout(G)
after you have built the graph (added all edges and nodes) and before you draw it.