def on_button_clicked(b): with output: display(Javascript('window.open("{url}");'.format(url=__doc_url)))
print(f"Sending code to {worker}") redis.rpush(f"js_inbox:{worker}", cell) # This is to be able to render React code display( Javascript(""" // Load our libraries from a CDN instead of wherever this notebook is hosted. require.config({ paths: { babel: '/files/lib/babel.min', react: '/files/lib/react.min', 'react-dom': '/files/lib/react-dom.min' } }) // Hook to call into Python. // Credit to disarticulate for documenting the usage of iopub: // https://gist.github.com/disarticulate/d06069ff3e71cf828e5329beab8cb084 window.python = code => new Promise((resolve, reject) => { IPython.notebook.kernel.execute( code, {iopub: {output: data => resolve(data.content.text)}}, ) }) """)) class LivePlot: def __init__(self, legend, xmin=None, xmax=None, ymin=None, ymax=None): self.fig = plt.figure(figsize=(8, 5)) self.ax = self.fig.add_subplot(1, 1, 1)
def render(cls): jscode = """ require(["@popperjs/core", "tippy"], function (popper, tippy) { tippy("[data-tippy-content]", %s); });""" % cls.ser_args display(Javascript(jscode))
def expose(cls, varname: str): """Expose the module to global scope""" jscode = f"require(['{cls.id()}'], function ({cls.id()}) {{ window.{varname} = {cls.id()} }});" display(Javascript(jscode))
def render(self): """ Customized renderer. Directly load the bundled index. """ display(Javascript(open(os.path.join(DIRECTORY, 'static', 'index.js')).read()))
def update_header(self, objective, variable): display( Javascript(""" jQuery("#objective-%s").text("%f");\n jQuery("#variable-%s").text("%f"); """ % (self.header_id, objective[1], self.header_id, variable[1])))
def _repr_javascript_(self): js = code % (self.bgcolor, self.width, self.height, self.url, self.magicmode, self.opacity) #js = Javascript(js, lib='http://get.goXTK.com/xtk_edge.js') js = Javascript(js, lib='files/xtk_edge.js') return js._repr_javascript_()
def head_view(attention, tokens, sentence_b_start=None, prettify_tokens=True): """Render head view Args: attention: list of ``torch.FloatTensor``(one for each layer) of shape ``(batch_size(must be 1), num_heads, sequence_length, sequence_length)`` tokens: list of tokens sentence_b_index: index of first wordpiece in sentence B if input text is sentence pair (optional) prettify_tokens: indicates whether to remove special characters in wordpieces, e.g. Ġ """ if sentence_b_start is not None: vis_html = """ <span style="user-select:none"> Layer: <select id="layer"></select> Attention: <select id="filter"> <option value="all">All</option> <option value="aa">Sentence A -> Sentence A</option> <option value="ab">Sentence A -> Sentence B</option> <option value="ba">Sentence B -> Sentence A</option> <option value="bb">Sentence B -> Sentence B</option> </select> </span> <div id='vis'></div> """ else: vis_html = """ <span style="user-select:none"> Layer: <select id="layer"></select> </span> <div id='vis'></div> """ display(HTML(vis_html)) __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(__file__))) vis_js = open(os.path.join(__location__, 'head_view.js')).read() if prettify_tokens: tokens = format_special_chars(tokens) bsz, n_heads, q_len, d_len = attention[0].shape pseudo_full = [ torch.zeros(bsz, n_heads, q_len + d_len, q_len + d_len) for _ in range(len(attention)) ] cross_attn = format_attention(attention) attn = format_attention(pseudo_full) attn_data = { 'all': { 'attn': attn.tolist(), 'left_text': tokens, 'right_text': tokens } } if sentence_b_start is not None: slice_a = slice( 0, sentence_b_start) # Positions corresponding to sentence A in input slice_b = slice( sentence_b_start, len(tokens)) # Position corresponding to sentence B in input attn_data['aa'] = { 'attn': attn[:, :, slice_a, slice_a].tolist(), 'left_text': tokens[slice_a], 'right_text': tokens[slice_a] } attn_data['bb'] = { 'attn': attn[:, :, slice_b, slice_b].tolist(), 'left_text': tokens[slice_b], 'right_text': tokens[slice_b] } attn_data['ab'] = { 'attn': cross_attn.tolist(), 'left_text': tokens[slice_a], 'right_text': tokens[slice_b] } attn_data['ba'] = { 'attn': attn[:, :, slice_b, slice_a].tolist(), 'left_text': tokens[slice_b], 'right_text': tokens[slice_a] } params = {'attention': attn_data, 'default_filter': "all"} attn_seq_len = len(attn_data['all']['attn'][0][0]) if attn_seq_len != len(tokens): raise ValueError( f"Attention has {attn_seq_len} positions, while number of tokens is {len(tokens)}" ) display(Javascript('window.params = %s' % json.dumps(params))) display(Javascript(vis_js))
def callMakeTrainPy(): display(Javascript('Jupyter.notebook.kernel.execute(\ "ClovirCM.makeTrainPy( " + "\'"\ +Jupyter.notebook.notebook_name+"\')");'))
def save_notebook(): from IPython.core.display import Javascript, display return display(Javascript("IPython.notebook.save_notebook()"), include=['application/javascript'])
def __init__(self, tbl: Union['DataFrame', ITable], table_class: str = 'display', columns: Optional[Union[dict, List[dict]]] = None, table_id: Optional[str] = None, **kwargs): """Show the Parameters ---------- tbl: Union[DataFrame, ITable] the data frame or an instance that implement the ITable class that we want to display table_class: str html classes for formatting the table's style: https://datatables.net/manual/styling/classes columns: Union[dict, List[dict]] custom definition for each column: https://datatables.net/reference/option/columns table_id: Optional[str] id of the table, manually giving the table an id helps reducing number of instances in the client as we store this data table in the client side to reduce the kwargs see the [examples](https://datatables.net/examples/index) and the [options](https://datatables.net/manual/options) the options will be passed directly to the client """ if not isinstance(tbl, ITable): # this should be dataframe self.table = ITableDataFrame(tbl) else: self.table = tbl self.table_class = table_class base_defs = [{"title": name} for name in self.table.columns()] if columns is not None: if isinstance(columns, list): assert len(columns) == len(base_defs) for i in range(len(base_defs)): assert isinstance(columns[i], dict) base_defs[i].update(columns[i]) else: assert isinstance(columns, dict) for i in range(len(base_defs)): base_defs[i].update(columns) self.columns = base_defs self.table_id = table_id or str(uuid4()) self.options = kwargs self.tunnel = SlowTunnelWidget(tunnel_id=self.table_id) self.tunnel.on_receive(self.on_receive_updates) self.el = widgets.HTML(value="") self.el_class_id = f"DataTable_{self.el.model_id}" self.el.add_class(self.el_class_id) # use pkg_resources instead of __file__ to support install package via `pip install -e .` jscode = read_file( Path(os.path.abspath(__file__)).parent / "DataTable.js") # jscode = read_file(pkg_resources.resource_filename("labext", "widgets/DataTable.js")) jscode += Template(""" require(['$JQueryId'], function (jquery) { $CallUntilTrue(function () { if (window.IPyCallback === undefined || window.IPyCallback.get("$tunnelId") === undefined) { return false; } let el = jquery(".$containerClassId > div.widget-html-content"); if (el.length === 0) { return false; } // fix the issue of horizontal scrolling (the size goes beyond the border as jupyter set overflow // to be visible) // DOM structure (* is the one we need to modify) // jp-Cell-outputArea // jp-OutputArea-child // jp-OutputArea-output * // widgets-output * // jp-OutputArea * // jp-OutputArea-child // jp-OutputArea-output * let ptr = el; while (!ptr.parent().hasClass("jp-Cell-outputArea")) { ptr.css('overflow-x', 'auto'); ptr.css('margin', '0px'); ptr = ptr.parent(); } if (window.$container.DataTable === undefined) { window.$container.DataTable = new Map(); } let tunnel = window.IPyCallback.get("$tunnelId"); let model = new LabExtDataTable( jquery, el, tunnel, $columns, "$table_class", $options ); model.render(); window.$container.DataTable.set("$tableId", model); return true; }, 100); }); """.strip()).substitute(JQueryId=M.JQuery.id(), CallUntilTrue=M.LabExt.call_until_true, container=M.LabExt.container, containerClassId=self.el_class_id, tableId=self.table_id, tunnelId=self.tunnel.tunnel_id, columns=ujson.dumps(self.columns), table_class=self.table_class, options=ujson.dumps(self.options)) self.el_auxiliaries = [self.tunnel, Javascript(jscode)] self.init_complete = False self.init_complete_callback = noarg_func self.on_draw_complete_callback = noarg_func self.on_redraw_complete_callback = noarg_func self.transform = identity_func
def init(): from IPython.core.display import display, Javascript path = os.path.abspath(os.path.dirname(__file__)) + "/" + JS_LOADER_FILE js_loader = open(path).read() return display(Javascript(js_loader))
def save(self, uid): """Save the value of the molecular diagram drawn in the widget to the Python namespace """ display(Javascript(f"saveAs_{uid}('{self.name}')"))
def execute_js(code): """Execute JavaScript code in a Notebook environment""" display(Javascript(code))
def plot(self, variable_name): from IPython.core.display import Javascript # import json # json_config = json.dumps(chart) this_id = self.this_id return Javascript( """ require.undef('mapboxglModule'); require.config({ paths: { highcharts: "http://code.highcharts.com/highcharts", highcharts_exports: "http://code.highcharts.com/modules/exporting", }, shim: { highcharts: { exports: "Highcharts", deps: ["jquery"] }, highcharts_exports: { exports: "Highcharts", deps: ["highcharts"] } } }); define('mapboxglModule', ["@jupyter-widgets/base", "highcharts_exports", "changePropagation"], (widgets, highcharts, changePropagation) => { let MapboxGLView = widgets.DOMWidgetView.extend({ defaults: _.extend({}, widgets.DOMWidgetModel.prototype.defaults, { value: '' }), placeholder_id : null, generate_placeholder_id : function() { return Math.random().toString(36).substring(7); }, render: function() { //this.value_changed(); console.log('placeholder id:', this.placeholder_id); if (this.placeholder_id === null){ this.placeholder_id = this.generate_placeholder_id(); } console.log('placeholder id:', this.placeholder_id); if($("#container").length == 0) { this.create_dom_element(); } function exec_code(context){ var kernel = IPython.notebook.kernel; var code_input = '""" + variable_name + """'; console.log('code input', code_input); var msg_id = kernel.execute(code_input, { iopub: { output: function(response) { // Print the return value of the Python code to the console var result = response.content.data["text/plain"].replace(/'/g, '"');; //console.log(result); var chart = JSON.parse(result) console.log('currently obtained chart', chart); context.display_highcharts(JSON.parse(result)); } } }, { silent: false, store_history: false, stop_on_error: true }); } exec_code(this); //this.model.on('change:value', this.value_changed, this); }, value_changed: function() { this.el.textContent = this.model.get('value').my_key; }, callback: function(e) { // function triggered as a result of user selecting a particular region var kernel = IPython.notebook.kernel; var code_input = '""" + variable_name + """'; var msg_id = kernel.execute(code_input, { iopub: { output: function(response) { var result = response.content.data["text/plain"].replace(/'/g, '"');; var chart = JSON.parse(result) console.log("printing unchanged config: " + chart.xAxis); chart.xAxis.max = e.max; chart.xAxis.min = e.min; var kernel = IPython.notebook.kernel; kernel.execute('chart["xAxis"]["min"] = '+e.min) kernel.execute('chart["xAxis"]["max"] = '+e.max) console.log(changePropagation); console.log(changePropagation.load_ipython_extension()) // changePropagation.load_ipython_extension(); changePropagation.invoke_change_propagation(); // changePropagation.change_propagation(); } } }, { silent: false, store_history: false, stop_on_error: true }); }, create_dom_element : function() { element.append('<div id=\"""" + this_id + """\" style="min-width: 310px; height: 400px; margin: 0 auto"></div>'); }, display_highcharts: function(chart) { // need to check if provided config file contains the following attributes // if it does do not overwrite. if (!chart.hasOwnProperty('xAxis')){ chart.xAxis = {}; } if (!chart.xAxis.hasOwnProperty('events')){ chart.xAxis.events = {}; } chart.xAxis.events.setExtremes = this.callback; var kernel = IPython.notebook.kernel; //var code_input = '""" + variable_name + """ = chart'; //var msg_id = kernel.execute(code_input, { // iopub: { // output: function(response) { // // Print the return value of the Python code to the console // var result = response.content.data["text/plain"].replace(/'/g, '"');; // var chart = JSON.parse(result) // //context.display_highcharts(JSON.parse(result)); // // } // } // }, // { // silent: false, // store_history: false, // stop_on_error: true // }); var this_id = '""" + this_id + """'; console.log('this id', this_id); console.log('about to display chart:',chart); var attached_chart = $('#'+this_id).highcharts(chart); console.log('attached_chart', attached_chart); }, }); return { MapboxGLView, }; }); """)
def get_auxiliary_components(self): selectize_options = """ valueField: '$valueField', searchField: $searchFields, options: $options, dropdownParent: 'body', create: $allowCreation, maxItems: $maxItems, items: $items, onChange: function (value) { window.IPyCallback.get("$valueTunnel").send_msg(JSON.stringify({ type: "set_value", value: value })); }, render: { item: function (item, escape) { return '<div>' + item['$itemField'] + '</div>'; }, option: function (item, escape) { return '<div>' + item['$optionField'] + '</div>'; } },""" if self.search_fn is not None: selectize_options += """ load: function (query, callback) { // send query let version = window.IPyCallback.get("$searchTunnel").send_msg(query); // register the callback to some where window.IPyCallback.get("$searchTunnel").on_receive((return_version, result) => { if (return_version < version) { // ignore the response as it's too old return; } result = JSON.parse(result); callback(result); }); }""" selectize_options = Template(selectize_options.strip()) \ .substitute(searchTunnel=self.el_search_tunnel.tunnel_id, valueTunnel=self.el_value_tunnel.tunnel_id, valueField=self.value_field, searchFields=ujson.dumps(self.search_fields), itemField=self.item_field, optionField=self.option_field, options=ujson.dumps(self.records), items=ujson.dumps(self.value if isinstance(self.value, list) else [self.value]), maxItems=self.max_items, allowCreation=str(self.allow_creation).lower()) jscode = Template(""" require(["$JQueryId", "$SelectizeId"], function (jquery, _) { $CallUntilTrue(function () { // get the selection container var $$el = jquery(".$uniqueClassId"); if (jquery('select', $$el).length == 0) { return false; } // make it looks beautiful jquery('select', $$el).selectize({ $selectizeOptions }); var selectize = jquery('select', $$el)[0].selectize; window.IPyCallback.get("$valueTunnel").on_receive((version, payload) => { let msg = JSON.parse(payload); if (msg.type == 'set_value') { if (msg.value == '') { selectize.clear(true); } else if (Array.isArray(msg.value)) { selectize.clear(true); for (let v of msg.value) { selectize.addItem(v, true); } } else { selectize.addItem(msg.value, true); } } else if (msg.type == 'replace_options') { selectize.clearOptions(); for (let record of msg.records) { selectize.addOption(record); } selectize.refreshOptions(false); } else if (msg.type == 'add_options') { for (let record of msg.records) { selectize.addOption(record); } selectize.refreshOptions(false); } }); window.IPyCallback.get("$valueTunnel").send_msg(JSON.stringify({"type": "initialized"})); return true; }, 100); }); """.strip()).substitute(JQueryId=JQuery.id(), SelectizeId=Selectize.id(), uniqueClassId=self.el_root_id, selectizeOptions=selectize_options, valueTunnel=self.el_value_tunnel.tunnel_id, CallUntilTrue=LabExt.call_until_true) return [ self.el_value_tunnel, self.el_search_tunnel, Javascript(jscode) ]
def build_stat_table(self, srcs, col): ht = "<style>" ht += "<head><style>#source { font-family: 'Trebuchet MS', Arial, Helvetica, sans-serif;font-szie: small; border-collapse: collapse; width: 100%; }" ht += "#header, #item {font-family: Arial, Helvetica, sans-serif;border-collapse: collapse; margin-left: 0px; width: 100%;}" ht += "#header tr, #item tr { border-radius: 20px;}" ht += "#item th {padding-top: 5px; padding-bottom: 5px; text-align: center; background-color: #503C42;color: white;}" ht += "#item td { border-radius: 10px;border: 2px solid #FFFFFF;padding: 5px;background-color: #d1c6b8;color: #503C42;}" ht += ".accordion {background-color: #A58F75;border-radius: 5px;color: #FFFFFF;cursor: pointer;padding: 2px;width: 100%;border: none;text-align: center;outline: none;font-size: 15px;transition: 0.5;}" ht += ".active { color: #DF8889; background-color: #f5f2f0; }" ht += ".accordion:hover {color:white;background-color: #6762AF; }" ht += '.accordion:after {content: "\\02795"; font-size: 13px;float: left;margin-left: 5px;}' ht += '.active:after { content: "\\2796"; }' ht += ".panel {display: none;}" ht += "</style>" for s in srcs: df = self.main_df[self.main_df[self.source_column] == s] num = len(df[self.dest_column].unique()) strs = "<b>Soruce %s </b>" % s ht += "<button class='accordion'>" + strs + "</button><div class='panel'>" ht += "<table id='item'><tr>" ht += "<td colspan=%d>" % len(col) ht += "<b>unique dest</b>: %d" % num ht += "</td></tr>" for c in range(len(col)): ht += "<th>%s</th>" % col[c] ht += "<tr>" for c in col: mean = df[c].mean() median = df[c].median() mode = df[c].mode()[0] cmin = df[c].min() cmax = df[c].max() ht += "<td>" ht += "<b>mean</b>: %.2f</br>" % mean ht += "<b>median</b>: %.2f</br>" % median ht += "<b>mode</b>: %.2f</br>" % mode ht += "<b>min</b>: %.2f</br>" % cmin ht += "<b>max</b>: %.2f</br>" % cmax ht += "</td>" ht += "</tr>" ht += "</table></div>" jht = "var acc = document.getElementsByClassName('accordion');" jht += "var i;" jht += "for (i = 0; i < acc.length; i++) {" jht += " acc[i].addEventListener('click', function() {" jht += " this.classList.toggle('active');" jht += " var panel = this.nextElementSibling;" jht += " if (panel.style.display === 'block') {" jht += " panel.style.display = 'none';" jht += " } else {" jht += " panel.style.display = 'block';" jht += " }" jht += " });" jht += "}" self.stat_table = widgets.HTML(value=ht) self.reload_data("Stats", self.stat_table) display(Javascript(jht))
def javascript(self, line, cell): """Run the cell block of Javascript code""" display(Javascript(cell))
def create_visual_diff_through_html(string1, string2, notebook=False, context_size=None, inline_view=False): """ The function uses `jsdifflib <https://github.com/cemerick/jsdifflib>`_ to create a visual diff. If it was not already done, the function downloads the tool using `pymyinstall <https://github.com/sdpython/pymyinstall>`_. @param string1 first string (anything such as an url, a file, a string, a stream) @param string2 second string (anything such as an url, a file, a string, a stream) @param notebook if True, the function assumes the outcome will be displayed from a notebook and does things accordingly, see below @param context_size to display everything (None) or just the changes > 0 @param inline_view only for notebook, True: one column, False: two columns @return html page or (`HTML <https://ipython.org/ipython-doc/stable/api/generated/IPython.display.html ?highlight=display#IPython.display.HTML>`_, `Javascript <https://ipython.org/ipython-doc/stable/api/generated/IPython.display.html ?highlight=display#IPython.display.Javascript>`_) object if *notebook* is True .. exref:: :title: Visualize the difference between two text files or strings :: with open("file1.txt","r",encoding="utf8") as f: text1 = f.read() with open("file2.txt","r",encoding="utf8") as f: text2 = f.read() pg = create_visual_diff_through_html(text1,text2) with open("page.html","w",encoding="utf8") as f: f.write(pg) import webbrowser webbrowser.open("page.html") .. versionchanged:: 1.1 Parameter *notebook*, *context_size*, *inline_view* were added. The function now uses @see fn read_content_ufs to retrieve the content. """ string1 = read_content_ufs(string1) string2 = read_content_ufs(string2) fold = os.path.abspath(os.path.split(__file__)[0]) if not os.path.exists(fold): raise FileNotFoundError("unable to find jsdifflib in: " + fold) def cleanh(s): return s.replace("&", "&").replace("<", "<").replace(">", ">") if notebook: rep_path = "" else: rep_path = fold + "/" if notebook: global js_page_nb from IPython.core.display import HTML, Javascript did = "diffid_" + \ str(datetime.datetime.now()).replace(":", "_") \ .replace("/", "_") \ .replace(".", "_") \ .replace(" ", "_") lib = [ os.path.join(fold, "diffview.js"), os.path.join(fold, "difflib.js"), ] lib = [read_content_ufs(_) for _ in lib] css = os.path.join(fold, "diffview.css") css = read_content_ufs(css) html = HTML( """<style>__CSS__</style> <div id="__ID__"> populating... </div>""" .replace("__ID__", did).replace("__CSS__", css)) vars = [ "var tview={0};".format(1 if inline_view else 0), "var csize='{0}';".format( "" if context_size is None else context_size), "var bt = '{0}';".format( string1.replace("\n", "\\n").replace("'", "\\'")), "var nt = '{0}';".format( string2.replace("\n", "\\n").replace("'", "\\'")) ] vars = "\n".join(vars) data = js_page_nb.replace("__ID__", did) \ .replace("__INSERT_VARIABLES__", vars) data = "\n".join(lib + [data]) js = Javascript(data=data, lib=[], css=[]) return html, js else: global html_page, css_page, body_page, js_page page = html_page.replace("__PATH__", rep_path) \ .replace("__BODY__", body_page) \ .replace("__STRI" + "NG1__", cleanh(string1)) \ .replace("__STRI" + "NG2__", cleanh(string2)) \ .replace("__JS__", js_page) \ .replace("__CSS__", css_page) \ .replace("__CONTEXT_SIZE__", "" if context_size is None else str(context_size)) \ .replace("__ID__", "diffoutput") return page
#Load the nbtutor extension #%load_ext nbtutor #Reset the notebook style from IPython.core.display import display, HTML, Javascript display( HTML( "<style>#notebook-container { width:50%; float:left !important;}</style>" )) display( Javascript(''' $(function() { $("#notebook-container").resizable({ handles: 'e', //containment: '#container', }); }); ''')) #https://stackoverflow.com/questions/4688162/jquery-resizable-dynamic-maxwidth-option #display(Javascript('document.getElementById("notebook-container").classList.add("ui-resizable");')) #display(HTML("<style>#notebook-container { width:50%; float:left !important; resize:horzontal; position: fixed; bottom: 0px; height: 100%;}</style>")) #<div class="ui-resizable-handle ui-resizable-e" style="z-index: 90;">::after</div> #Launch the simulator from nbev3devsim import ev3devsim_nb as eds #%load_ext nbev3devsim roboSim = eds.Ev3DevWidget()
def show(model, model_type, tokenizer, sentence_a, sentence_b=None, display_mode='dark', layer=None, head=None): # Generate unique div id to enable multiple visualizations in one notebook if sentence_b: vis_html = """ <div id="bertviz" style='padding:8px'> <span style="user-select:none"> <span class="dropdown-label">Layer: </span><select id="layer"></select> <span class="dropdown-label">Head: </span><select id="att_head"></select> <span class="dropdown-label">Attention: </span><select id="filter"> <option value="all">All</option> <option value="aa">Sentence A -> Sentence A</option> <option value="ab">Sentence A -> Sentence B</option> <option value="ba">Sentence B -> Sentence A</option> <option value="bb">Sentence B -> Sentence B</option> </select> </span> <div id='vis'></div> </div> """ else: vis_html = """ <div id="bertviz" style='padding:8px'> <span style="user-select:none"> <span class="dropdown-label">Layer: </span><select id="layer"></select> <span class="dropdown-label">Head: </span> <select id="att_head"></select> </span> <div id='vis'></div> </div> """ display(HTML(vis_html)) __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(__file__))) attn_data = get_attention(model, model_type, tokenizer, sentence_a, sentence_b, include_queries_and_keys=True) if model_type == 'gpt2': bidirectional = False else: bidirectional = True params = { 'attention': attn_data, 'default_filter': "all", 'bidirectional': bidirectional, 'display_mode': display_mode, 'layer': layer, 'head': head } vis_js = open(os.path.join(__location__, 'neuron_view.js')).read() display(Javascript('window.bertviz_params = %s' % json.dumps(params))) display(Javascript(vis_js))
def delete_above_cell(): display( Javascript('''var c = IPython.notebook.get_selected_index(); IPython.notebook.get_cell(c-1).metadata.editable = true; IPython.notebook.get_cell(c-1).metadata.deletable = true; IPython.notebook.delete_cell([c-1]);'''))
def gmap_init(): js = """ window.gmap_initialize = function() {}; $.getScript('https://maps.googleapis.com/maps/api/js?v=3&sensor=false&callback=gmap_initialize'); """ return Javascript(data=js)
def head_view(attention, tokens, sentence_b_start=None, prettify_tokens=True): """Render head view Args: attention: list of ``torch.FloatTensor``(one for each layer) of shape ``(batch_size(must be 1), num_heads, sequence_length, sequence_length)`` tokens: list of tokens sentence_b_start: index of first wordpiece in sentence B if input text is sentence pair (optional) prettify_tokens: indicates whether to remove special characters in wordpieces, e.g. Ġ """ # Generate unique div id to enable multiple visualizations in one notebook vis_id = 'bertviz-%s' % (uuid.uuid4().hex) if sentence_b_start is not None: vis_html = """ <div id='%s'> <span style="user-select:none"> Layer: <select id="layer"></select> Attention: <select id="filter"> <option value="all">All</option> <option value="aa">Sentence A -> Sentence A</option> <option value="ab">Sentence A -> Sentence B</option> <option value="ba">Sentence B -> Sentence A</option> <option value="bb">Sentence B -> Sentence B</option> </select> </span> <div id='vis'></div> </div> """ % (vis_id) else: vis_html = """ <div id='%s'> <span style="user-select:none"> Layer: <select id="layer"></select> </span> <div id='vis'></div> </div> """ % (vis_id) if prettify_tokens: tokens = format_special_chars(tokens) attn = format_attention(attention) attn_data = { 'all': { 'attn': attn.tolist(), 'left_text': tokens, 'right_text': tokens } } if sentence_b_start is not None: slice_a = slice( 0, sentence_b_start) # Positions corresponding to sentence A in input slice_b = slice( sentence_b_start, len(tokens)) # Position corresponding to sentence B in input attn_data['aa'] = { 'attn': attn[:, :, slice_a, slice_a].tolist(), 'left_text': tokens[slice_a], 'right_text': tokens[slice_a] } attn_data['bb'] = { 'attn': attn[:, :, slice_b, slice_b].tolist(), 'left_text': tokens[slice_b], 'right_text': tokens[slice_b] } attn_data['ab'] = { 'attn': attn[:, :, slice_a, slice_b].tolist(), 'left_text': tokens[slice_a], 'right_text': tokens[slice_b] } attn_data['ba'] = { 'attn': attn[:, :, slice_b, slice_a].tolist(), 'left_text': tokens[slice_b], 'right_text': tokens[slice_a] } params = { 'attention': attn_data, 'default_filter': "all", 'root_div_id': vis_id } attn_seq_len = len(attn_data['all']['attn'][0][0]) if attn_seq_len != len(tokens): raise ValueError( f"Attention has {attn_seq_len} positions, while number of tokens is {len(tokens)}" ) display(HTML(vis_html)) __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(__file__))) vis_js = open(os.path.join(__location__, 'head_view.js')).read().replace( "PYTHON_PARAMS", json.dumps(params)) display(Javascript(vis_js))
def head_view(attention=None, tokens=None, sentence_b_start=None, prettify_tokens=True, layer=None, heads=None, encoder_attention=None, decoder_attention=None, cross_attention=None, encoder_tokens=None, decoder_tokens=None, include_layers=None): """Render head view Args: For self-attention models: attention: list of ``torch.FloatTensor``(one for each layer) of shape ``(batch_size(must be 1), num_heads, sequence_length, sequence_length)`` tokens: list of tokens sentence_b_start: index of first wordpiece in sentence B if input text is sentence pair (optional) For encoder-decoder models: encoder_attention: list of ``torch.FloatTensor``(one for each layer) of shape ``(batch_size(must be 1), num_heads, encoder_sequence_length, encoder_sequence_length)`` decoder_attention: list of ``torch.FloatTensor``(one for each layer) of shape ``(batch_size(must be 1), num_heads, decoder_sequence_length, decoder_sequence_length)`` cross_attention: list of ``torch.FloatTensor``(one for each layer) of shape ``(batch_size(must be 1), num_heads, decoder_sequence_length, encoder_sequence_length)`` encoder_tokens: list of tokens for encoder input decoder_tokens: list of tokens for decoder input For all models: prettify_tokens: indicates whether to remove special characters in wordpieces, e.g. Ġ layer: index (zero-based) of initial selected layer in visualization. Defaults to layer 0. heads: Indices (zero-based) of initial selected heads in visualization. Defaults to all heads. include_layers: Indices (zero-based) of layers to include in visualization. Defaults to all layers. Note: filtering layers may improve responsiveness of the visualization for long inputs. """ attn_data = [] if attention is not None: if tokens is None: raise ValueError("'tokens' is required") if encoder_attention is not None or decoder_attention is not None or cross_attention is not None \ or encoder_tokens is not None or decoder_tokens is not None: raise ValueError( "If you specify 'attention' you may not specify any encoder-decoder arguments. This" " argument is only for self-attention models.") if include_layers is None: include_layers = list(range(num_layers(attention))) attention = format_attention(attention, include_layers) if sentence_b_start is None: attn_data.append({ 'name': None, 'attn': attention.tolist(), 'left_text': tokens, 'right_text': tokens }) else: slice_a = slice(0, sentence_b_start ) # Positions corresponding to sentence A in input slice_b = slice( sentence_b_start, len(tokens)) # Position corresponding to sentence B in input attn_data.append({ 'name': 'All', 'attn': attention.tolist(), 'left_text': tokens, 'right_text': tokens }) attn_data.append({ 'name': 'Sentence A -> Sentence A', 'attn': attention[:, :, slice_a, slice_a].tolist(), 'left_text': tokens[slice_a], 'right_text': tokens[slice_a] }) attn_data.append({ 'name': 'Sentence B -> Sentence B', 'attn': attention[:, :, slice_b, slice_b].tolist(), 'left_text': tokens[slice_b], 'right_text': tokens[slice_b] }) attn_data.append({ 'name': 'Sentence A -> Sentence B', 'attn': attention[:, :, slice_a, slice_b].tolist(), 'left_text': tokens[slice_a], 'right_text': tokens[slice_b] }) attn_data.append({ 'name': 'Sentence B -> Sentence A', 'attn': attention[:, :, slice_b, slice_a].tolist(), 'left_text': tokens[slice_b], 'right_text': tokens[slice_a] }) elif encoder_attention is not None or decoder_attention is not None or cross_attention is not None: if encoder_attention is not None: if encoder_tokens is None: raise ValueError( "'encoder_tokens' required if 'encoder_attention' is not None" ) if include_layers is None: include_layers = list(range(num_layers(encoder_attention))) encoder_attention = format_attention(encoder_attention, include_layers) attn_data.append({ 'name': 'Encoder', 'attn': encoder_attention.tolist(), 'left_text': encoder_tokens, 'right_text': encoder_tokens }) if decoder_attention is not None: if decoder_tokens is None: raise ValueError( "'decoder_tokens' required if 'decoder_attention' is not None" ) if include_layers is None: include_layers = list(range(num_layers(decoder_attention))) decoder_attention = format_attention(decoder_attention, include_layers) attn_data.append({ 'name': 'Decoder', 'attn': decoder_attention.tolist(), 'left_text': decoder_tokens, 'right_text': decoder_tokens }) if cross_attention is not None: if encoder_tokens is None: raise ValueError( "'encoder_tokens' required if 'cross_attention' is not None" ) if decoder_tokens is None: raise ValueError( "'decoder_tokens' required if 'cross_attention' is not None" ) if include_layers is None: include_layers = list(range(num_layers(cross_attention))) cross_attention = format_attention(cross_attention, include_layers) attn_data.append({ 'name': 'Cross', 'attn': cross_attention.tolist(), 'left_text': decoder_tokens, 'right_text': encoder_tokens }) else: raise ValueError("You must specify at least one attention argument.") if layer is not None and layer not in include_layers: raise ValueError( f"Layer {layer} is not in include_layers: {include_layers}") # Generate unique div id to enable multiple visualizations in one notebook vis_id = 'bertviz-%s' % (uuid.uuid4().hex) # Compose html if len(attn_data) > 1: options = '\n'.join( f'<option value="{i}">{attn_data[i]["name"]}</option>' for i, d in enumerate(attn_data)) select_html = f'Attention: <select id="filter">{options}</select>' else: select_html = "" vis_html = f""" <div id='%s'> <span style="user-select:none"> Layer: <select id="layer"></select> {select_html} </span> <div id='vis'></div> </div> """ % (vis_id) for d in attn_data: attn_seq_len_left = len(d['attn'][0][0]) if attn_seq_len_left != len(d['left_text']): raise ValueError( f"Attention has {attn_seq_len_left} positions, while number of tokens is {len(d['left_text'])} " f"for tokens: {' '.join(d['left_text'])}") attn_seq_len_right = len(d['attn'][0][0][0]) if attn_seq_len_right != len(d['right_text']): raise ValueError( f"Attention has {attn_seq_len_right} positions, while number of tokens is {len(d['right_text'])} " f"for tokens: {' '.join(d['right_text'])}") if prettify_tokens: d['left_text'] = format_special_chars(d['left_text']) d['right_text'] = format_special_chars(d['right_text']) params = { 'attention': attn_data, 'default_filter': "0", 'root_div_id': vis_id, 'layer': layer, 'heads': heads, 'include_layers': include_layers } # require.js must be imported for Colab or JupyterLab: display( HTML( '<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>' )) display(HTML(vis_html)) __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(__file__))) vis_js = open(os.path.join(__location__, 'head_view.js')).read().replace( "PYTHON_PARAMS", json.dumps(params)) display(Javascript(vis_js))