netAn1: Neural Network Analysis Plotting Functions
for sqd error and responses of hidden and output cells.
Notebook Version: 2.0
Steve Hunka, University of Alberta, steve.hunka@ualberta.ca
Mod. Date: Oct 27/97 Mod to V3.0

General Description of Notebook netAn1

This Notebook contains plotting functions useful in gaining some understanding of the dynamic and final state characteristics of the back propagated neural network for a particular problem.  The functions use the data stored in the error-squared, hidden response, and output response files written during execution of the neural network simulation function bpnn in the Notebook Neural.nb.  Data saved in these files can be extensive, e.g., error-squared values are stored at each iteration and all other data at each epoch.  The examples use data from the files TCLe2, TCLor, and TCLhr written by option in the function bpnn in Neural.nb.
Caution: A large number of plots may result in using some functions depending upon the number of input cells, hidden cells, output cells, and exemplars used for a particular problem.  For example, a function may create one plot for each exemplar and if the number of exemplars is large, a considerable amount of memory will be required.

Required Packages

<< "Graphics`Graphics3D`"<< "netUtil`"

Description of Functions
Three types of functions are used:
1) functions which use error sqd data, hidden cell responses,
    and output cell response data,
2) functions which are called by those in (1) to do the plotting, and
3) support functions to provide interactive parameter input from the keyboard,
    and read the required data from a file.

Functions:
The functions described below are all designed to take input from one of the 3 files written by the neural network program bpnn.  Each of these files contains values saved at each iteration (error-squared file only) or at each epoch.  The first 3 characters of the function names listed below identify the nature of the data file from which the function requires data:
err     error-squared file of order (#iterations,#output cells)
hdr    hidden layer response file of order (#epochs,#exemplars,#hidden cells)
otr     output layer response file of order (#epochs,#output cells,#exemplars)


errAnlz:   plots sqd error at each output cell; option single plot for each output
               cell or one plot displaying sqd error for all output cells.
               X axis: iterations; Y axis: sqd error.
otrAnlz:  plots response from each output cell for each exemplar
              Plots: 1 plot for each output cell; X axis: epochs; Y axis: response
              value.  Each line: an exemplar                            
hdrAnlz1: 3D point/line plot; plots hidden layer response output for each
               exemplar for 3 hidden cells (i,j,k) selected by the user
              	Plots: 1 plot; X axis=hc[i]; Y axis=hc[j]; Z axis=hc[k]
              	Each line: 1 exemplar
hdrAnlz2: multiple line plots for each hidden cell response; 
               Plots: 1 for each hidden cell, X axis=epochs, Y axis=response value
               Each line: an exemplar
hdrAnlz3: plots response value for all hidden cells in one plot for each exemplar
               Plots: one plot for each exemplar, X axis=epochs, Y axis: response value
               Each line: a hidden cell
hdrAnlz4: plots joint response values of two hidden cells as coordinates
               Plots: 1 for each exemplar (optional) and combined plot
               X axis: hc[j] response, Y axis: hc[k] response
               Each line: an exemplar
hdrAnlz5: 3D surface plot; response for hc[j] by exemplar by epoch plotted
               separately for each j selected by user
               Plots: 1 for each hidden cell; X axis: exemplar id; Y axis: epochs
               Z axis: response value

      
Supporting Plot Functions:

plotLists3: plots coordinates (x1,y1), (x2,y2)... cols of matrix; option for 
                single/multiple line plots
splt3d:      3D line/point plot; plots (x,y,z) at each epoch; options: point
                or line plot, single/multiple line plot; start/end numbering of lines
srfPlot3d: surface plot 3d; Plot is exemplar by epoch by response value of
             hc[j]. One 3D plot is made for each hidden cell.

The following functions are in the Package netUtil.nb:
kbin3, kbinstrg, inpvec, getFdata, timeDate, plotnLists, plotLegend. Their documentation is in netUdoc.nb.

Documentation for function getFdata:

Since this function is used extensively to read data from a file a brief documentation of the user input is provided. (The function is in the Package netUtil.nb and its documentation in netUdoc.nb. 
 
The user is asked to input the name of the file holding the data; if the file is found a message is given; if the file is not found a message is given and the user is asked to give another name. If the user enters "quit" at the point of entering a file name, the function returns to the calling function indicating no data was read. If the file is available the user is asked whether to use all the data or only part of it. If the user enters "all", all data is read; if "part" is entered, the user is asked to give the starting point (record) in the file and the ending point for which the data is wanted.

Expected File Structure of Input Data

File Structures as Loaded by Neural Program bpnn.
Caution:Structures which follow assume fixed order of exemplar input to the neural network program generating the files. An iteration is the presentation of one exemplar, an epoch the presentation of all exemplars once. If the option in the neural network program is for random presentation of exemplars, then the output of the hidden layer response data  and output cell responses data does not follow the natural order of presentation of exemplars as assumed in the functions of this notebook.  
  
The following abbreviations apply:
ic[[i]]     ith input cell               hc[[j]]     jth hidden cell
oc[[k]]    kth output cell            ex[[n]]     nth exemplar
#ic  number of input cells          #hc   number of hidden cells
#oc number of output cells        #ex   number of exemplars

errorfile: 
            {oc[[1]], oc[[2]],.....oc[[k]]} repeated for each iteration
   Dimensions={#iterations,#oc}
            
hidden layer response:
     {
       {hc[[1]], hc[[2]],...hc[[j]]},  for exemplar 1
         {hc[[1]], hc[[2]],...hc[[j]]},  for exemplar 2
         .................
         {hc[[1]], hc[[2]],...hc[[j]]},   for exemplar n
     } 
   repeated for each epoch. Dimensions={#epochs,#ex,#hc}

hidden cell weight file
    {
      {ic[[1]], ic[[2]],....ic[[i]]}, for hidden cell 1
      {ic[[1]], ic[[2]],....ic[[i]]}, for hidden cell 2
      ...............
      {ic[[1]], ic[[2]],....ic[[i]]}   for hidden cell j
    }   repeated for each epoch. Dimensions={#epochs,#hc,#ic}
    
output cell weight file
  {
     {hc[[1]], hc[[2]],.....hc[[j]]}, output cell 1
     {hc[[1]], hc[[2]],.....hc[[j]]}, output cell 2
      ...........
       {hc[[1]], hc[[2]],.....hc[[j]]} output cell k
  } repeated for each epoch. Dimensions={#epochs,#oc,#hc}
    
output cell response file
 {
   {ex[[1]], ex[[2]], ...,ex[[n]]},  output cell 1
   {ex[[1]], ex[[2]], ...,ex[[n]]},  output cell 2
   ..........
   {ex[[1]], ex[[2]], ...,ex[[n]]},  output cell k
 } repeated for each epoch. Dimensions={#epochs,#oc,#ex}

splt3d[d_,ttl_] 3D line plot of joint parameters over epochs of 3 cells defined by user. 
d is the cell output or weights from the neural network usually stored in a file;
ttl is a title for the plot.
The user input options are:
a) whether each plot should be marked with an id number at the start or end of
    the line or dots plotted.
b) whether lines or points are to be plotted; if points, the point size is
    requested.
c) whether single 3d plots should be made in addition to the combined plot.
   ScatterPlot3D produces Graphics3D[{Point[{x,y,z}],.....},options]; it is
   changed to give Graphics3D[{PointSize[ps],Point[{x,y,z}],.....},options
    in each pobj[j]. Also the first or last point is changed to Text[j,{x,y,z}]
    depending upon option (a) above.
d) the cell data to use, e.g., {1,2,5} plots point as defined by cells 1, 2 and 5. 
e) whether more plots are wanted after the first, to allow user to select other
    cells.
 Note: 
 1)PlotRange->All has been set. If PlotRange->Automatic, then if in (a) "end" is selected an id number may not appear for a specific plot because the plot was truncated.
 2) d is of order (#epochs, #z,#hidden cells) where #z may be number of output cells, number of exemplars, or number of input cells depending on the calling function. 
Calls: kbinstrg, kbin3,inpvec
Rqrs: <<Graphics`Graphics3D`, <<netUtil`
V3.0 Mod: ScatterPlot3D now has a directive GrayLevel[0] in the InputForm of the graphic object which is not in V2.2; changes to indices for line numbering were required.
Mod. Date: Oct 14/97 for V3.0

\(\(splt3d[d_, ttl_] := 
      Module[{p, ans, ln, pobj, temp, ps, ept, ipt, hcv, dt, qplt}, 
        ept = \(Dimensions[d]\)[[1]]; 
        p = \(Dimensions[d]\)[[2]]; 
        qplt = "y"; 
        While["y" == qplt, 
          ans = kbinstrg[
              "Mark start or end?", {{"start"}, {"end"}}]; 
          Print["Line id=", ans]; If[ans == "start", ept = 2]; 
          ans = kbinstrg[
              "Join plotted points? y/n", {{"y"}, {"n"}}]; 
          If[ans == "n",  (*plot\ points\ only*) 
				ln = False; 
            ps = kbin3["Type point size", 0.01]; 
            \(Print["Point size=", ps]; \), \(ln = True; \)]; 
          ipt = kbinstrg["Single plots? y/n", {{"y"}, {"n"}}]; 
          If[ipt == "y", ipt = $DisplayFunction, ipt = Identity]; 
          hcv = inpvec[{1, 
                \(Dimensions[d]\)[[3]]}, 
              3, "hidden cells"]; Print["Selected Cells=", hcv]; 
          pobj = {}; 
          dt = \(Transpose[d, {2, 3, 1}]\)[[hcv
              ]]; dt = Transpose[dt, {3, 2, 1}]; 
          pobj = MapThread[
              ScatterPlot3D[#1, PlotJoined -> ln, Axes -> True, 
                  AxesLabel -> ToString/@hcv, PlotRange -> All, 
                  DisplayFunction -> ipt]&, {dt}]; 

          				 (*now\ mark\ start\ or\ end\ of\ points\ or\ lines*) 	

          					
          If[ans == "n",  (*set\ ps\ size\ directive*) \(Do[
              temp = Append[{PointSize[ps]}, 
                  \(pobj[[j
                      ]]\)[[1
                    ]]]; 
              pobj = ReplacePart[pobj, temp, {j, 1}]; 

              				 (*
                set\ point\ line\ number\ at\ start\ or\ end\ by\ ept*) 	

              					
              \(pobj = 
                pobj /. 
                  pobj[[j, 1, 2, ept]] 
                    -> 
                    Text[ToString[j], 
                      pobj[[j, 1, 2, ept, 1
                        ]]]; \)

              							, {j, 1, p}]; 
            \),  (*else\ set\ line\ line\ number*) 
				
            \(Do[temp = 
                Append[{
                    Text[ToString[j], 
                      pobj[[j, 1, 2, 1, ept
                        ]]]}, 
                  pobj[[j, 1]]]; 
              \(pobj[[j]] = 
                ReplacePart[pobj[[j]], 
                  temp, 1]; \), {j, 1, p}]; \)]; 
			
          Show[pobj, PlotLabel -> ttl, 
            DisplayFunction -> $DisplayFunction]; 
          qplt = kbinstrg["More plots? y/n", {{"y"}, {"n"}}]; ]; 
        
	Return[pobj]; 
	
	]; \)\)

srfPlot3d[d_]: surface plot 3d; d is 3d data matrix. Plot is exemplar by epoch by response value of hc[j]. One 3D plot is made for each hidden cell.
User Input: 
a) Number of plots to be made; 
b) vector of hidden cell indices for which plots are desired, and 
c) whether more plots are wanted.
Note: ColorFunction->Hue, but the user may wish to try RGB by removing comment surrounding the appropriate statements, and commenting out the reference to Hue.
Calls: clr2,kbin3, kbinstrg,inpvec
Mod. Date: Mar 25/97

\(\(srfPlot3d[d_] := 
      Module[{dflat, nhc, ttl, dt, more, np, inx}, dflat = Flatten[d]; 
        nhc = \(Dimensions[d]\)[[3]]; 
        dt = Transpose[d, {3, 2, 1}]; more = "y"; 
        While[more == "y", np = kbin3["How many plots?", 1]; 
          inx = inpvec[{1, nhc}, np, "hidden cells"]; 
          dtx = dt[[inx]]; i = 0; 
          MapThread[
            ListPlot3D[Transpose[#1], ColorFunction -> Hue, 

                	 (*ColorFunction -> \((clr2[#]&)\), 
                  ColorOutput -> RGBColor, *) 				
					
                Mesh -> False, PlotRange -> All, 
                AxesLabel 
                  -> {"exemplars", "epochs", "response"}, 
                PlotLabel -> 
                  StringInsert["Hidden cell=", 
                    ToString[
                      inx[[i = i + 1]]], 
                    \(-1\)]]&, {dtx}]; 
          more = kbinstrg[
              "More plots? y/n", {{"y"}, {"n"}}]; ]; ]; \)\)

clr2[y] is a color function which could be used by srfPlot3d

clr2[y_] := 
      Which[y ≤  .39, RGBColor[1, 0, 0], y ≥  .61, 
        RGBColor[0, 0, 1], y < 1.0, RGBColor[0, 1, 0]];

plotLists3[m,tl,xu,yu] plots adjacent columns of matrix m as (x,y) for each exemplar. Lines or points are plotted, and end points are marked by a number as well as being in color. See function plotnLists for color sequence, or execute function plotLegend.
m is the matrix,
tl is plot title
xu is x-axis label
yu is the y-axis label
User Input:
a) single plots (y/n); if n one plot with multiple lines
b) points joined or not
Calls: kbinstrg
Mod. Date: Mar 9/97

\(\(plotLists3[m_, tl_, xu_, yu_] := 
      Module[{ans, pobj, colr, ipt, tempobj, ln, ept, etxt}, 
        If[OddQ[\(Dimensions[m]\)[[2
                ]]] == True, 
          Print["Error:odd # cols in data"]; Return[]]; pobj = {}; 
        colr = {0. , 0. , 0. , 0. , 0. , 1. , 0. , 1. , 0. , 0. , 1. , 1. , 
            1. , 0. , 0. , 1. , 0. , 1. , 1. , 1. , 0. , 0. , 0. ,  .5, 
            0. ,  .5, 0. , 0. ,  .5,  .5,  .5, 0. , 0. ,  .5, 0. ,  .5}; 
        ipt = kbinstrg["Single plots? y/n", {{"y"}, {"n"}}]; 
        If[ipt == "y", ipt = $DisplayFunction, ipt = Identity]; 
        ans = kbinstrg[
            "Join plotted points? y/n", {{"y"}, {"n"}}]; 
        If[ans == "n", \(ln = False; \), \(ln = True; \)]; 
        ept = \(Dimensions[m]\)[[1]]; 
        Do[tempobj = 
            ListPlot[
              Transpose[
                \(Transpose[m]\)[[{i, i + 1}
                    ]]], AxesLabel -> {xu, yu}, 
              PlotJoined -> ln, PlotRange -> All, 
              PlotStyle 
                -> {
                  RGBColor[colr[[1]], 
                    colr[[2]], 
                    colr[[3]]]}, 
              DisplayFunction -> Identity]; colr = RotateLeft[colr, 3]; 
          If[ans == "n", 
				 (*replace\ Point[{x, y}]*) 
				
            \(tempobj = 
              tempobj /. 
                tempobj[[1, 2, ept]] 
                  -> 
                  Text[ToString[\(i + 1\)\/2], 
                    tempobj[[1, 2, ept, 1
                      ]]]; \), 

            			 (*else\ append\ to\ Line[{x, y}]*) 	
				
            etxt = Append[{
                  Text[ToString[\(i + 1\)\/2], 
                    tempobj[[1, 2, 1, ept
                      ]]]}, 
                tempobj[[1]]]; 
            tempobj[[1]] = 
              ReplacePart[tempobj[[1]], 
                etxt, 2]; ]; 
          tempobj = 
            ReplacePart[tempobj, 
              Append[{PointSize[ .001]}, 
                tempobj[[1]]], 1]; 
          Show[tempobj, DisplayFunction -> ipt]; 
          \(AppendTo[pobj, tempobj]; \), {i, 1, Length[Transpose[m]], 2}]; 
        Show[pobj, PlotLabel -> tl, 
          DisplayFunction -> $DisplayFunction]; ]; \)\)

errAnlz: plots the error squared at each output cell as a single plot. The squared error data are read from a file written by the neural network simulation program bpnn, and is of order (#iterations,#outcells)
User Input: See function getFdata and plotnLists
Calls: getFdata,timeDate,kbin3,kbinstrng,plotnLists,plotLegend
Note: If there is wide variability in the values of error-squared for more than one output cell and a large number of iterations, a single plot of the error curves is likely to produce curves which appear to have solid colors throughout the range of the x-axis. In such cases, the RMS error output from the neural simulation function bpnn provides a better representation of the nature of the convergence towards minimum sqd error. 
Mod. Date: Mar 22/97

errAnlz := 
      Module[{ttl, data, extnt, xunits, sp = 0, mp = 0, pn = 0}, 
        Print["Plot of Sqd-error at Output Cells"]; {data, extnt} = 
          getFdata; If[0 == extnt, Print["No data read"]; Return[]]; 
        If["y" == 
            kbinstrg[
              "Single plots for each output cell? y/n", {{"y"}, {
                  "n"}}], sp = 1]; 
        If["y" == 
            kbinstrg[
              "One plot of all error curves? y/n", {{"y"}, {
                  "n"}}], mp = 1]; 
        If["y" == 
            kbinstrg[
              "Place number at end of each line? y/n", {{"y"}, {
                  "n"}}], pn = 1]; 
        ttl = " Sqd-error for Iterations="; 
        ttl = StringInsert[ttl, ToString[extnt], -1]; 
        plotLegend[
          Dimensions[data][[2]]]; 
        plotnLists[data, ttl, "iterations", sp, mp, pn]; ];

errAnlz

otrAnlz:  plots the output from each output cell for each exemplar. The user may select to plot the output for each exemplar as a single plot, or to have all exemplars represented in a single plot for each output cell. Data are taken from file of output cell responses created by neural network program bpnn and is of order (#epochs, #outcells, #exemplars). 
User Input: See functions getFdata and plotnLists
Calls: getFdata,timeDate,kbin3,kbinstrng,plotnLists,plotLegend
Mod. Date: Mar 22/97

otrAnlz := 
      Module[{ttl, data, extnt, xflat, notc, nx}, 
        Print["Output cell response for each exemplar"]; 
        Print["plots=oc[j]; Yaxis=resp value; Xaxis=epoch"]; 
        Print["1 line/exemplar"]; {data, extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        nx = Dimensions[data][[3]]; 
        Print["Number of exemplars=", nx]; 
        notc = Dimensions[data][[2
            ]]; 
        Print["Number of output cells=", notc]; xflat = Flatten[data]; 
        plotLegend[
          Dimensions[data][[3]]]; 
        Do[ttl = "Cell:  Output for epochs="; 
          ttl = StringInsert[ttl, ToString[extnt], -1]; 
          ttl = StringInsert[ttl, ToString[i], 7]; 
          plotnLists[Partition[Drop[xflat, (i - 1) nx], nx, notc nx], 
              ttl, "epochs", 0, 1, 1];, {i, 1, notc}]; ];

otrAnlz

hdrAnlz1: plots migration of hidden cell response for each exemplar. Plot is 3D of (hc1,hc2,hc3) at each epoch for each exemplar. Each dot is an epoch; each line is an exemplar; axes are hidden cell response values. The data is taken from the hidden response file written by bpnn, and is of order (epochs, #exemplars, #hidden cells).
User Input: 
a) See getFdata; splt3d user input is:
b) whether lines to be identified at start or end
c) whether plotted points are joined; if no, point size requested
d) whether single plots for each line to be displayed
e) indices of 3 hidden cells as a vector
f) option to plot using new vector of 3 hidden cells.
Calls: getFdata,timeDate, kbin3,kbinstrng,splt3d
Rqd Packages: <<Graphics`Graphics3D`
Mod. Date: Mar 22/97

hdrAnlz1 := 
      Module[{data, extnt}, 
        Print["Response of 3 hidden cells to exemplars"]; 
        Print["Xaxis=hc[i];Yaxis=hc[j];Zaxis=hc[k]"]; 
        Print["User specifies 3 hidden cells as vector"]; 
        Print["Line[j]=exemplar[j]"]; {data, extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        Print["Number of exemplars=", 
          Dimensions[data][[2]]]; 
        Print["Number of hidden cells=", 
          Dimensions[data][[3]]]; 
        splt3d[data, "Hidden Cell Response"]; ];

hdrAnlz1

hdrAnlz2: plots response to all exemplars by epochs for each hidden cell separately. Data is taken from file created by neural network program bpnn and is of order (#epochs,#exemplars,#hidden cells).
User Input:
a) See getFdata
Calls: getFdata, timeDate,plotnLists,kbin3,kbinstrg,plotLegend
Mod. Date: Mar 23/97

hdrAnlz2 := 
      Module[{data, extnt, ttl, nhc}, 
        Print["Response to exemplars by each hidden cell"]; 
        Print["Plots =hc[j]; Xaxis=epoch; Yaxis=response value"]; 
        Print["Line=exemplar[k]"]; {data, extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        Print["Number of exemplars=", 
          Dimensions[data][[2]]]; 
        nhc = Dimensions[data][[3]]; 
        Print["Number of hidden cells=", nhc]; 
        plotLegend[
          Dimensions[data][[2]]]; 
        Do[ttl = StringInsert["Hidden cell=", ToString[i], -1]; 
          plotnLists[
              Transpose[
                Transpose[data, {3, 2, 1}][[i
                  ]]], ttl, "epoch", 0, 1, 1];, {i, 
            1, nhc}]; ];

hdrAnlz2

hdrAnlz3 multiple line plot of response value of each hidden cell by epoch separately for each exemplar. There are as many multiple line plots as exemplars. Data is of order (#epochs,#exemplars,#hidden cells). 
User Input: see getFdata
Calls:plotnLists,plotLegend
Mod. Date: Mar 23/97

hdrAnlz3 := 
      Module[{data, extnt, ttl, ne}, 
        Print["Response of each hidden cell by epoch"]; 
        Print["Plots=exemplar[j]; Xaxis=epoch"]; 
        Print["Yaxis=response value; line=hc[k]"]; {data, extnt} = 
          getFdata; If[0 == extnt, Print["No data read"]; Return[]]; 
        ne = Dimensions[data][[2]]; 
        Print["Number of exemplars=", ne]; 
        Print["Number of hidden cells=", 
          Dimensions[data][[3]]]; 
        plotLegend[
          Dimensions[data][[3]]]; 
        Do[ttl = StringInsert["Exemplar=", ToString[i], -1]; 
          plotnLists[
              Transpose[data, {2, 1, 3}][[i
                ]], ttl, "epoch", 0, 1, 1];, {i, 1, 
            ne}]; ];

hdrAnlz3

hdrAnlz4: plots joint response of 2 user selected hidden cells for each exemplar as line or one point per epoch. Except for differences in text printed, this function is the same as hdwAnlz4.  Data is of order (#epochs, #exemplars, #hidden cells). 
User Input:
a) See function getFdata
b) 2 hidden cell indices as vector
c) See function plotLists3
d) option to plot other pairs of hidden cells 
Calls: plotLists3,kbin3,kbinstrg,getFdata,timeDate,plotLegend,inpvec
Mod. Date: Mar 25/97

hdrAnlz4 := 
      Module[{ans, alpr, pr, data, extnt, ttl, ne, nhc, data2, ax, ay}, 
        Print["Joint response to exemplars by a pair of hidden cells"]; 
        Print["Xaxis=response hc[j];Yaxis=response hc[k];Lineid=end"]; {
            data, extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        ne = Dimensions[data][[2]]; 
        nhc = Dimensions[data][[3]]; 
        Print["Number hidden cells=", nhc]; 
        Print["Number of exemplars=", ne]; plotLegend[ne]; ans = "y"; 
        While[ans == "y", pr = inpvec[{1, nhc}, 2, "hidden cells"]; 
          Print["Hidden cell pair to plot=", pr]; alpr = {}; 
          Do[AppendTo[alpr, pr + j {nhc, nhc}]; , {j, 0, ne - 1}]; 
          data2 = Transpose[
              Flatten[Transpose[data, {3, 1, 2}], 1]
                  [[Flatten[alpr]]]]; 
          ay = StringInsert["h", 
              ToString[pr[[2]]], 
              -1]; 
          ax = StringInsert["h", 
              ToString[pr[[1]]], 2]; 
          ttl = StringInsert["Hidden cells=", ToString[pr], -1]; 
          plotLists3[data2, ttl, ax, ay]; 
          ans = kbinstrg[
              "More plots? y/n", {{"y"}, {"n"}}]; ]; ];

hdrAnlz4

hdrAnlz5: 3D surface plot of exemplar by epoch by response value separately for each hidden cell requested by user. Data are read from hidden cell response file written by neural network program bpnn and is of order (#epochs, #exemplars, #hidden cells).
User Input: 
a) See getFdata; srfPlot3d requests are
b) number of hidden cell response plots to be made
b) vector of hidden cell indices for which plots are desired, and 
c) whether more plots are wanted. 
Calls: getFdata,timeDate, kbin3, kbinstrg, srfPlot3d.
Mod. Date: Mar 23/97

hdrAnlz5 := 
      Module[{data, extnt}, 
        Print["Exemplar by epoch by hidden cell response"]; 
        Print["User selects indices of hidden cells to plot"]; {data, 
            extnt} = getFdata; 
        If[0 == extnt, Print["No data read"]; Return[]]; 
        Print["Number of hidden cells=", 
          Dimensions[data][[3]]]; 
        Print["Number of exemplars=", 
          Dimensions[data][[2]]]; 
        srfPlot3d[data]; ];

hdrAnlz5